Source for gnu.java.awt.font.opentype.NameDecoder

   1: /* NameDecoder.java -- Decodes names of OpenType and TrueType fonts.
   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.io.UnsupportedEncodingException;
  41: import java.nio.ByteBuffer;
  42: import java.util.Locale;
  43: 
  44: 
  45: /**
  46:  * A utility class that helps with decoding the names of OpenType
  47:  * and TrueType fonts.
  48:  *
  49:  * @author Sascha Brawer (brawer@dandelis.ch)
  50:  */
  51: public class NameDecoder
  52: {
  53:   public static final int NAME_COPYRIGHT = 0;
  54: 
  55: 
  56:   /**
  57:    * Specifies the name of the family to which a font belongs, for
  58:    * example “Univers”.
  59:    */
  60:   public static final int NAME_FAMILY = 1;
  61: 
  62: 
  63:   /**
  64:    * Specified the name of the font inside its family, for
  65:    * example “Light”.
  66:    */
  67:   public static final int NAME_SUBFAMILY = 2;
  68: 
  69: 
  70:   public static final int NAME_UNIQUE = 3;
  71: 
  72: 
  73:   /**
  74:    * Specifies the full human-readable name of a font, for example
  75:    * “Univers Light”
  76:    */
  77:   public static final int NAME_FULL = 4;
  78: 
  79: 
  80:   public static final int NAME_VERSION = 5;
  81: 
  82: 
  83:   /**
  84:    * Specifies the PostScript name of a font, for example
  85:    * “Univers-Light”.
  86:    */
  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:     /* We understand only format 0 of the name table. */
 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:       // Handle PS seperately as it can be only ASCII, although
 147:       // possibly encoded as UTF-16BE
 148:       if ( name == NAME_POSTSCRIPT )
 149:         {
 150:           if( nameTable.get(nameStart) == 0 ) // Peek at top byte
 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: /* Azerbaijani/Cyrillic */
 168:             match = (nameLanguage == /* Azerbaijani/Arabic */ 50)
 169:               || (nameLanguage == /* Azerbaijani/Roman */ 150);
 170:             break;
 171: 
 172:           case 57: /* Mongolian/Mongolian */
 173:             match = (nameLanguage == /* Mongolian/Cyrillic */ 58);
 174:             break;
 175: 
 176:           case 83: /* Malay/Roman */
 177:             match = (nameLanguage == /* Malay/Arabic */ 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:   /**
 204:    * The language codes used by the Macintosh operating system.  MacOS
 205:    * defines numeric language identifiers in the range [0 .. 95] and
 206:    * [128 .. 150]. To map this numeric identifier into an ISO 639
 207:    * language code, multiply it by two and take the substring at that
 208:    * position.
 209:    *
 210:    * <p>ISO 639 has revised the code for some languages, namely
 211:    * <code>he</code> for Hebrew (formerly <code>iw</code>),
 212:    * <code>yi</code> (formerly <code>ji</code>), and <code>id</code>
 213:    * for Indonesian (formerly <code>in</code>). In those cases, this
 214:    * table intentionally contains the older, obsolete code.  The
 215:    * reason is that this is the code which
 216:    * java.util.Locale.getLanguage() is specified to return.  The
 217:    * implementation of {@link #getMacLanguageCode} depends on this.
 218:    *
 219:    * @see <a href=
 220:    * "http://www.unicode.org/unicode/onlinedat/languages.html"
 221:    * >Language Codes: ISO 639, Microsoft and Macintosh</a>
 222:    */
 223:   private static final String macLanguageCodes
 224:     // 0                   1                   2
 225:     // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
 226:     = "enfrdeitnlsvesdaptnoiwjaarfielismttrhrzhurhithkoltplhuetlv  "
 227: 
 228:     // 3                   4                   5
 229:     // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
 230:     + "fofaruzhnlgdsqrocssksljisrmkbgukbeuzkkazazhykamokytgtkmnmnps"
 231: 
 232:     // 6                   7                   8
 233:     // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
 234:     + "kukssdbonesamrbnasgupaormlkntatesimykmloviintlmsmsamti  sosw"
 235: 
 236:     // 9                   10                  11
 237:     // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
 238:     + "rwrn  mgeo                                                  "
 239: 
 240:     // 12                  13                  14
 241:     // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
 242:     + "                cyeucalaqugnayttugtsjwsuglafbriugdgvgatoelkl"
 243: 
 244:     // 15
 245:     // 0
 246:     + "az";
 247: 
 248: 
 249:   /**
 250:    * The primary language IDs used by the Microsoft operating systems.
 251:    *
 252:    * <p>ISO 639 has revised the code for some languages, namely
 253:    * <code>he</code> for Hebrew (formerly <code>iw</code>),
 254:    * <code>yi</code> (formerly <code>ji</code>), and <code>id</code>
 255:    * for Indonesian (formerly <code>in</code>). In those cases, this
 256:    * table intentionally contains the older, obsolete code.  The
 257:    * reason is that this is the code which
 258:    * java.util.Locale.getLanguage() is specified to return.  The
 259:    * implementation of {@link #getMicrosoftLanguageCode} depends on
 260:    * this.
 261:    *
 262:    * @see <a href=
 263:    * "http://www.unicode.org/unicode/onlinedat/languages.html"
 264:    * >Language Codes: ISO 639, Microsoft and Macintosh</a>
 265:    */
 266:   private static final String microsoftLanguageCodes
 267:     // 0                   1                   2
 268:     // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
 269:     = "  arbgcazhcsdadeelenesfifriwhuisitjakonlnoplptrmrorushsksqsv"
 270: 
 271:     // 3                   4                   5
 272:     // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
 273:     + "thtrurinukbesletlvlttgfavihyazeu  mk  ts    xhzuafkafohimt  "
 274: 
 275:     // 6                   7                   8
 276:     // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
 277:     + "gajimskkkyswtkuzttbnpaguortateknmlasmrsamnbocykmlomygl    sd"
 278: 
 279:     // 9                   10                  11
 280:     // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
 281:     + "  si  iuam  ksnefypstl      ha  yo              omtign  laso";
 282: 
 283: 
 284:   /**
 285:    * Maps a Java Locale into a MacOS language code.
 286:    *
 287:    * <p>For languages that are written in several script systems,
 288:    * MacOS defines multiple language codes. Java Locales have a
 289:    * variant which could be used for that purpose, but a small
 290:    * test program revealed that with Sun's JDK 1.4.1_01, only two
 291:    * of 134 available Locales have a variant tag (namely no_NO_NY
 292:    * and th_TH_TH).</p>
 293:    *
 294:    * <p>The following cases are problematic:
 295:    *
 296:    * <ul> <li>Azerbaijani (az): The MacOS language code is 49 if
 297:    * Azerbaijani is written in the Cyrillic script; 50 if written in
 298:    * the Arabic script; 150 if written in the Roman script.  This
 299:    * method will always return 49 for the Azerbaijani locale.</li>
 300:    *
 301:    * <li>Mongolian (mn): The MacOS language code is 57 if Mongolian is
 302:    * written in the Mongolian script; 58 if written in the Cyrillic
 303:    * script. This method will always return 57 for the Mongolian
 304:    * locale.</li>
 305:    *
 306:    * <li>Malay (ms): The MacOS language code is 83 if Malay is written
 307:    * in the Roman script; 84 if written in the Arabic script. This
 308:    * method will always return 83 for the Malay locale.</li> </ul>
 309:    *
 310:    * @return a MacOS language code, or -1 if there is no such code for
 311:    * <code>loc</code>&#x2019;s language.
 312:    */
 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:       /* Traditional Chinese (MacOS language #19) and and Simplified
 325:        * Chinese (MacOS language #33) both have "zh" as their ISO 639
 326:        * code.
 327:        */
 328:       if (loc.equals(Locale.SIMPLIFIED_CHINESE))
 329:         code = 33;
 330:       break;
 331: 
 332:       // Other special cases would be 49, 57 and 83, but we do not
 333:       // know what do do about them. See the method documentation for
 334:       // details.
 335:     }
 336: 
 337:     return code;
 338:   }
 339: 
 340: 
 341:   /**
 342:    * Maps a Java Locale into a Microsoft language code.
 343:    */
 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:         /* Microsoft uses code 26 for "sh" (Serbo-Croatian),
 359:          * "hr" (Croatian) and "sr" (Serbian). Our table contains
 360:          * "sh".
 361:          */
 362:         code = 26;
 363:       }
 364:       else if (isoCode.equals("gd"))
 365:       {
 366:         /* Microsoft uses code 60 for "gd" (Scottish Gaelic) and
 367:          * "ga" (Irish Gaelic). Out table contains "ga".
 368:          */
 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:       /* The index must be even to be considered a match. Otherwise, we
 391:        * could match with the second letter of one language and the
 392:        * first of antoher one.
 393:        */
 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:   /**
 444:    * Maps a MacOS language code into a Java Locale.
 445:    *
 446:    * @param macLanguageCode the MacOS language code for
 447:    * the language whose Java locale is to be retrieved.
 448:    *
 449:    * @return an suitable Locale, or <code>null</code> if
 450:    * the mapping cannot be performed.
 451:    */
 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:   /**
 482:    * Maps a Windows LCID into a Java Locale.
 483:    *
 484:    * @param lcid the Windows language ID whose Java locale
 485:    * is to be retrieved.
 486:    *
 487:    * @return an suitable Locale, or <code>null</code> if
 488:    * the mapping cannot be performed.
 489:    */
 490:   private static Locale getWindowsLocale(int lcid)
 491:   {
 492:     /* FIXME: This is grossly incomplete. */
 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:   /**
 523:    * Maps a Macintosh Script Manager code to the name of the
 524:    * corresponding Java Charset.
 525:    *
 526:    * @param macScript a MacOS ScriptCode, for example
 527:    * 6 for <code>smGreek</code>.
 528:    *
 529:    * @return a String that can be used to retrieve a Java
 530:    * CharsetDecorder, for example <code>MacGreek</code>, or
 531:    * <code>null</code> if <code>macScript</code> has an
 532:    * unsupported value.
 533:    */
 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:   /**
 577:    * Maps a Microsoft locale ID (LCID) to the name of the
 578:    * corresponding Java Charset.
 579:    *
 580:    * @param lcid the Microsoft locale ID.
 581:    *
 582:    * @return a String that can be used to retrieve a Java
 583:    * CharsetDecorder, for example <code>windows-1252</code>, or
 584:    * <code>null</code> if <code>lcid</code> has an unsupported value.
 585:    */
 586:   private static String getMicrosoftCharsetName(int lcid)
 587:   {
 588:     int lang;
 589:     char codePage = '?';
 590: 
 591:     /* Extract the language code from the LCID. */
 592:     lang = lcid & 0x3ff;
 593: 
 594:     /* In the majority of cases, the language alone determines the
 595:      * codepage.
 596:      */
 597:     if (lang < 100)
 598:       codePage = (" 612D022322225022EC2202201?002A462110777 68 ?2 1  "
 599:                   + "    2 2     2112 ?1           1     2           2 ")
 600:         .charAt(lang);
 601: 
 602:     /* There are a few exceptions, however, where multiple code pages
 603:      * are used for the same language. */
 604:     if (codePage == '?')
 605:     {
 606:       switch (lcid)
 607:       {
 608:       case 0x041a: // Croatian --> Windows-1250 (Central Europe)
 609:       case 0x081a: // Serbian (Latin) --> Windows-1250 (Central Europe)
 610:         codePage = '0';
 611:         break;
 612: 
 613:       case 0x42c: // Azeri (Latin) --> Windows-1254 (Turkish)
 614:       case 0x443: // Uzbek (Latin) --> Windows-1254 (Turkish)
 615:         codePage = '4';
 616:         break;
 617: 
 618:       case 0x82c: // Azeri (Cyrillic) --> Windows-1251 (Cyrillic)
 619:       case 0x843: // Uzbek (Cyrillic) --> Windows-1251 (Cyrillic)
 620:       case 0xc1a: // Serbian (Cyrillic) --> Windows-1251 (Cyrillic)
 621:         codePage = '1';
 622:         break;
 623:       }
 624:     }
 625: 
 626:     switch (codePage)
 627:     {
 628:     case '0': return "windows-1250"; // Central Europe
 629:     case '1': return "windows-1251"; // Cyrillic
 630:     case '2': return "windows-1252"; // Latin 1
 631:     case '3': return "windows-1253"; // Greek
 632:     case '4': return "windows-1254"; // Turkish
 633:     case '5': return "windows-1255"; // Hebrew
 634:     case '6': return "windows-1256"; // Arabic
 635:     case '7': return "windows-1257"; // Baltic
 636:     case '8': return "windows-1258"; // Vietnam
 637:     case 'A': return "windows-874";  // Thai
 638:     case 'B': return "windows-936";  // Simplified Chinese, GBK
 639:     case 'C': return "windows-949";  // Korean
 640:     case 'D': return "windows-950";  // Traditional Chinese, Big5
 641:     case 'E': return "windows-932";  // Japanese Shift-JIS
 642:     default: return null;
 643:     }
 644:   }
 645: 
 646: 
 647:   /**
 648:    * Returns the Locale of an OpenType name.
 649:    *
 650:    * @param platform the OpenType platform ID.
 651:    *
 652:    * @param language the language tag of the OpenType name. If
 653:    * <code>platform</code> is 1, this is the MacOS language code.
 654:    *
 655:    * @param encoding the encoding tag of the OpenType name. If
 656:    * <code>platform</code> is 1, this is the MacOS script code.
 657:    */
 658:   public static Locale getLocale(int platform, int language, int encoding)
 659:   {
 660:     switch (platform)
 661:     {
 662:     case 1: /* Apple Macintosh */
 663:       return getMacLocale(language);
 664: 
 665:     case 3: /* Microsoft Windows */
 666:       return getWindowsLocale(language);
 667: 
 668:     default:
 669:       return null;
 670:     }
 671:   }
 672: 
 673: 
 674:   /**
 675:    * Determines the name of the charset for an OpenType font name.
 676:    *
 677:    * @param platform the OpenType platform ID.
 678:    *
 679:    * @param language the language tag of the OpenType name. If
 680:    * <code>platform</code> is 1, this is the MacOS language code.
 681:    *
 682:    * @param encoding the encoding tag of the OpenType name. If
 683:    * <code>platform</code> is 1, this is the MacOS script code.
 684:    *
 685:    * @return a charset name such as <code>&quot;MacRoman&quot;</code>,
 686:    * or <code>null</code> if the combination is not known.
 687:    */
 688:   public static String getCharsetName(int platform, int language, int encoding)
 689:   {
 690:     switch (platform)
 691:     {
 692:     case 1: /* Apple Macintosh */
 693:       return getMacCharsetName(encoding);
 694: 
 695:     case 3: /* Microsoft Windows */
 696:       return getMicrosoftCharsetName(language);
 697: 
 698:     default:
 699:       return null;
 700:     }
 701:   }
 702: }