1:
37:
38: package ;
39:
40: import ;
41: import ;
42: import ;
43:
44:
45:
51: public class NameDecoder
52: {
53: public static final int NAME_COPYRIGHT = 0;
54:
55:
56:
60: public static final int NAME_FAMILY = 1;
61:
62:
63:
67: public static final int NAME_SUBFAMILY = 2;
68:
69:
70: public static final int NAME_UNIQUE = 3;
71:
72:
73:
77: public static final int NAME_FULL = 4;
78:
79:
80: public static final int NAME_VERSION = 5;
81:
82:
83:
87: public static final int NAME_POSTSCRIPT = 6;
88:
89:
90: public static final int NAME_TRADEMARK = 7;
91: public static final int NAME_MANUFACTURER = 8;
92: public static final int NAME_DESIGNER = 9;
93: public static final int NAME_DESCRIPTION = 10;
94: public static final int NAME_VENDOR_URL = 11;
95: public static final int NAME_DESIGNER_URL = 12;
96: public static final int NAME_LICENSE = 13;
97: public static final int NAME_LICENSE_URL = 14;
98: public static final int NAME_PREFERRED_FAMILY = 16;
99: public static final int NAME_PREFERRED_SUBFAMILY = 17;
100: public static final int NAME_FULL_MACCOMPATIBLE = 18;
101: public static final int NAME_SAMPLE_TEXT = 19;
102: public static final int NAME_POSTSCRIPT_CID = 20;
103:
104:
105: private static final int PLATFORM_MACINTOSH = 1;
106: private static final int PLATFORM_MICROSOFT = 3;
107:
108:
109: public static String getName(ByteBuffer nameTable,
110: int name, Locale locale)
111: {
112: int numRecords;
113: int macLanguage, msLanguage;
114: int offset;
115: int namePlatform, nameEncoding, nameLanguage, nameID, nameLen;
116: int nameStart;
117: String result;
118: boolean match;
119:
120: if (nameTable == null)
121: return null;
122:
123: nameTable.position(0);
124:
125: if (nameTable.getShort() != 0)
126: return null;
127:
128: macLanguage = getMacLanguageCode(locale);
129: msLanguage = getMicrosoftLanguageCode(locale);
130: numRecords = nameTable.getShort();
131: offset = nameTable.getShort();
132:
133: for (int i = 0; i < numRecords; i++)
134: {
135: namePlatform = nameTable.getShort();
136: nameEncoding = nameTable.getShort();
137: nameLanguage = nameTable.getShort();
138: nameID = nameTable.getShort();
139: nameLen = nameTable.getShort();
140: nameStart = offset + nameTable.getShort();
141:
142:
143: if (nameID != name)
144: continue;
145:
146:
147:
148: if ( name == NAME_POSTSCRIPT )
149: {
150: if( nameTable.get(nameStart) == 0 )
151: result = decodeName("UTF-16BE", nameTable, nameStart, nameLen);
152: else
153: result = decodeName("ASCII", nameTable, nameStart, nameLen);
154: return result;
155: }
156:
157: match = false;
158: switch (namePlatform)
159: {
160: case PLATFORM_MACINTOSH:
161: if ((nameLanguage == macLanguage) || (locale == null))
162: match = true;
163: else
164: {
165: switch (macLanguage)
166: {
167: case 49:
168: match = (nameLanguage == 50)
169: || (nameLanguage == 150);
170: break;
171:
172: case 57:
173: match = (nameLanguage == 58);
174: break;
175:
176: case 83:
177: match = (nameLanguage == 84);
178: break;
179: }
180: }
181: break;
182:
183: case PLATFORM_MICROSOFT:
184: if (((nameLanguage & 0xff) == msLanguage) || (locale == null))
185: match = true;
186: break;
187: }
188:
189:
190: if (match)
191: {
192: result = decodeName(namePlatform, nameEncoding, nameLanguage,
193: nameTable, nameStart, nameLen);
194: if (result != null)
195: return result;
196: }
197: }
198:
199: return null;
200: }
201:
202:
203:
223: private static final String macLanguageCodes
224:
225:
226: = "enfrdeitnlsvesdaptnoiwjaarfielismttrhrzhurhithkoltplhuetlv "
227:
228:
229:
230: + "fofaruzhnlgdsqrocssksljisrmkbgukbeuzkkazazhykamokytgtkmnmnps"
231:
232:
233:
234: + "kukssdbonesamrbnasgupaormlkntatesimykmloviintlmsmsamti sosw"
235:
236:
237:
238: + "rwrn mgeo "
239:
240:
241:
242: + " cyeucalaqugnayttugtsjwsuglafbriugdgvgatoelkl"
243:
244:
245:
246: + "az";
247:
248:
249:
266: private static final String microsoftLanguageCodes
267:
268:
269: = " arbgcazhcsdadeelenesfifriwhuisitjakonlnoplptrmrorushsksqsv"
270:
271:
272:
273: + "thtrurinukbesletlvlttgfavihyazeu mk ts xhzuafkafohimt "
274:
275:
276:
277: + "gajimskkkyswtkuzttbnpaguortateknmlasmrsamnbocykmlomygl sd"
278:
279:
280:
281: + " si iuam ksnefypstl ha yo omtign laso";
282:
283:
284:
313: private static int getMacLanguageCode(Locale loc)
314: {
315: int code;
316:
317: if (loc == null)
318: return -1;
319:
320: code = findLanguageCode(loc.getLanguage(), macLanguageCodes);
321: switch (code)
322: {
323: case 19:
324:
328: if (loc.equals(Locale.SIMPLIFIED_CHINESE))
329: code = 33;
330: break;
331:
332:
333:
334:
335: }
336:
337: return code;
338: }
339:
340:
341:
344: private static int getMicrosoftLanguageCode(Locale locale)
345: {
346: String isoCode;
347: int code;
348:
349: if (locale == null)
350: return -1;
351:
352: isoCode = locale.getLanguage();
353: code = findLanguageCode(isoCode, microsoftLanguageCodes);
354: if (code == -1)
355: {
356: if (isoCode.equals("hr") || isoCode.equals("sr"))
357: {
358:
362: code = 26;
363: }
364: else if (isoCode.equals("gd"))
365: {
366:
369: code = 60;
370: }
371: }
372: return code;
373: }
374:
375:
376: private static int findLanguageCode(String lang, String langCodes)
377: {
378: int index;
379: if (lang == null)
380: return -1;
381:
382: if (lang.length() != 2)
383: return -1;
384:
385: index = 0;
386: do
387: {
388: index = langCodes.indexOf(lang, index);
389:
390:
394: }
395: while (!((index < 0) || ((index & 1) == 0)));
396: if (index < 0)
397: return -1;
398:
399: index = index / 2;
400: return index;
401: }
402:
403:
404: private static String decodeName(int platform, int encoding, int language,
405: ByteBuffer buffer, int offset, int len)
406: {
407: String charsetName = getCharsetName(platform, language, encoding);
408: if (charsetName == null)
409: return null;
410:
411: return decodeName(charsetName, buffer, offset, len);
412: }
413:
414: private static String decodeName(String charsetName,
415: ByteBuffer buffer, int offset, int len)
416: {
417: byte[] byteBuf;
418: int oldPosition;
419:
420: byteBuf = new byte[len];
421: oldPosition = buffer.position();
422: try
423: {
424: buffer.position(offset);
425: buffer.get(byteBuf);
426: try
427: {
428: return new String(byteBuf, charsetName);
429: }
430: catch (UnsupportedEncodingException uex)
431: {
432: }
433: }
434: finally
435: {
436: buffer.position(oldPosition);
437: }
438:
439: return null;
440: }
441:
442:
443:
452: private static Locale getMacLocale(int macLanguageCode)
453: {
454: String isoCode;
455:
456: switch (macLanguageCode)
457: {
458: case 0: return Locale.ENGLISH;
459: case 1: return Locale.FRENCH;
460: case 2: return Locale.GERMAN;
461: case 3: return Locale.ITALIAN;
462: case 11: return Locale.JAPANESE;
463: case 23: return Locale.KOREAN;
464: case 19: return Locale.TRADITIONAL_CHINESE;
465: case 33: return Locale.SIMPLIFIED_CHINESE;
466: }
467:
468: if ((macLanguageCode < 0) || (macLanguageCode > 150))
469: return null;
470:
471: isoCode = macLanguageCodes.substring(macLanguageCode << 1,
472: (macLanguageCode + 1) << 1);
473: if (isoCode.charAt(0) == ' ')
474: return null;
475:
476: return new Locale(isoCode);
477: }
478:
479:
480:
481:
490: private static Locale getWindowsLocale(int lcid)
491: {
492:
493: switch (lcid)
494: {
495: case 0x0407: return Locale.GERMAN;
496: case 0x0408: return new Locale("el", "GR");
497: case 0x0409: return Locale.ENGLISH;
498: case 0x040b: return new Locale("fi");
499: case 0x040c: return Locale.FRENCH;
500: case 0x0416: return new Locale("pt");
501: case 0x0807: return new Locale("de", "CH");
502: case 0x0809: return new Locale("en", "UK");
503: case 0x080c: return new Locale("fr", "BE");
504: case 0x0816: return new Locale("pt", "BR");
505: case 0x0c07: return new Locale("de", "AT");
506: case 0x0c09: return new Locale("en", "AU");
507: case 0x0c0c: return new Locale("fr", "CA");
508: case 0x1007: return new Locale("de", "LU");
509: case 0x1009: return new Locale("en", "CA");
510: case 0x100c: return new Locale("fr", "CH");
511: case 0x1407: return new Locale("de", "LI");
512: case 0x1409: return new Locale("en", "NZ");
513: case 0x140c: return new Locale("fr", "LU");
514: case 0x1809: return new Locale("en", "IE");
515:
516: default:
517: return null;
518: }
519: }
520:
521:
522:
534: private static String getMacCharsetName(int macScript)
535: {
536: switch (macScript)
537: {
538: case 0: return "MacRoman";
539: case 1: return "MacJapanese";
540: case 2: return "MacKorean";
541: case 3: return "MacTradChinese";
542: case 4: return "MacArabic";
543: case 5: return "MacHebrew";
544: case 6: return "MacGreek";
545: case 7: return "MacCyrillic";
546: case 8: return "MacRSymbol";
547: case 9: return "MacDevanagari";
548: case 10: return "MacGurmukhi";
549: case 11: return "MacGujarati";
550: case 12: return "MacOriya";
551: case 13: return "MacBengali";
552: case 14: return "MacTamil";
553: case 15: return "MacTelugu";
554: case 16: return "MacKannada";
555: case 17: return "MacMalayalam";
556: case 18: return "MacSinhalese";
557: case 19: return "MacBurmese";
558: case 20: return "MacKhmer";
559: case 21: return "MacThai";
560: case 22: return "MacLao";
561: case 23: return "MacGeorgian";
562: case 24: return "MacArmenian";
563: case 25: return "MacSimpChinese";
564: case 26: return "MacTibetan";
565: case 27: return "MacMongolian";
566: case 28: return "MacEthiopic";
567: case 29: return "MacCentralEurope";
568: case 30: return "MacVietnamese";
569: case 31: return "MacExtArabic";
570:
571: default: return null;
572: }
573: }
574:
575:
576:
586: private static String getMicrosoftCharsetName(int lcid)
587: {
588: int lang;
589: char codePage = '?';
590:
591:
592: lang = lcid & 0x3ff;
593:
594:
597: if (lang < 100)
598: codePage = (" 612D022322225022EC2202201?002A462110777 68 ?2 1 "
599: + " 2 2 2112 ?1 1 2 2 ")
600: .charAt(lang);
601:
602:
604: if (codePage == '?')
605: {
606: switch (lcid)
607: {
608: case 0x041a:
609: case 0x081a:
610: codePage = '0';
611: break;
612:
613: case 0x42c:
614: case 0x443:
615: codePage = '4';
616: break;
617:
618: case 0x82c:
619: case 0x843:
620: case 0xc1a:
621: codePage = '1';
622: break;
623: }
624: }
625:
626: switch (codePage)
627: {
628: case '0': return "windows-1250";
629: case '1': return "windows-1251";
630: case '2': return "windows-1252";
631: case '3': return "windows-1253";
632: case '4': return "windows-1254";
633: case '5': return "windows-1255";
634: case '6': return "windows-1256";
635: case '7': return "windows-1257";
636: case '8': return "windows-1258";
637: case 'A': return "windows-874";
638: case 'B': return "windows-936";
639: case 'C': return "windows-949";
640: case 'D': return "windows-950";
641: case 'E': return "windows-932";
642: default: return null;
643: }
644: }
645:
646:
647:
658: public static Locale getLocale(int platform, int language, int encoding)
659: {
660: switch (platform)
661: {
662: case 1:
663: return getMacLocale(language);
664:
665: case 3:
666: return getWindowsLocale(language);
667:
668: default:
669: return null;
670: }
671: }
672:
673:
674:
688: public static String getCharsetName(int platform, int language, int encoding)
689: {
690: switch (platform)
691: {
692: case 1:
693: return getMacCharsetName(encoding);
694:
695: case 3:
696: return getMicrosoftCharsetName(language);
697:
698: default:
699: return null;
700: }
701: }
702: }