src/solaris/classes/sun/awt/X11FontManager.java

Print this page
rev 9717 : 8039642: Fix raw and unchecked warnings in sun.awt.*
Reviewed-by:


  42     private static final int POINT_SIZE_FIELD = 8;
  43     private static final int RESOLUTION_X_FIELD = 9;
  44     private static final int RESOLUTION_Y_FIELD = 10;
  45     private static final int SPACING_FIELD = 11;
  46     private static final int AVERAGE_WIDTH_FIELD = 12;
  47     private static final int CHARSET_REGISTRY_FIELD = 13;
  48     private static final int CHARSET_ENCODING_FIELD = 14;
  49 
  50     /*
  51      * fontNameMap is a map from a fontID (which is a substring of an XLFD like
  52      * "-monotype-arial-bold-r-normal-iso8859-7")
  53      * to font file path like
  54      * /usr/openwin/lib/locale/iso_8859_7/X11/fonts/TrueType/ArialBoldItalic.ttf
  55      * It's used in a couple of methods like
  56      * getFileNameFomPlatformName(..) to help locate the font file.
  57      * We use this substring of a full XLFD because the font configuration files
  58      * define the XLFDs in a way that's easier to make into a request.
  59      * E.g., the -0-0-0-0-p-0- reported by X is -*-%d-*-*-p-*- in the font
  60      * configuration files. We need to remove that part for comparisons.
  61      */
  62     private static Map fontNameMap = new HashMap();
  63 
  64     /*
  65      * xlfdMap is a map from a platform path like
  66      * /usr/openwin/lib/locale/ja/X11/fonts/TT/HG-GothicB.ttf to an XLFD like
  67      * "-ricoh-hg gothic b-medium-r-normal--0-0-0-0-m-0-jisx0201.1976-0"
  68      * Because there may be multiple native names, because the font is used
  69      * to support multiple X encodings for example, the value of an entry in
  70      * this map is always a vector where we store all the native names.
  71      * For fonts which we don't understand the key isn't a pathname, its
  72      * the full XLFD string like :-
  73      * "-ricoh-hg gothic b-medium-r-normal--0-0-0-0-m-0-jisx0201.1976-0"
  74      */
  75     private static Map xlfdMap = new HashMap();
  76 
  77     /* xFontDirsMap is also a map from a font ID to a font filepath.
  78      * The difference from fontNameMap is just that it does not have
  79      * resolved symbolic links. Normally this is not interesting except
  80      * that we need to know the directory in which a font was found to
  81      * add it to the X font server path, since although the files may
  82      * be linked, the fonts.dir is different and specific to the encoding
  83      * handled by that directory. This map is nulled out after use to free
  84      * heap space. If the optimal path is taken, such that all fonts in
  85      * font configuration files are referenced by filename, then the font
  86      * dir can be directly derived as its parent directory.
  87      * If a font is used by two XLFDs, each corresponding to a different
  88      * X11 font directory, then precautions must be taken to include both
  89      * directories.
  90      */
  91      private static Map xFontDirsMap;
  92 
  93      /*
  94       * This is the set of font directories needed to be on the X font path
  95       * to enable AWT heavyweights to find all of the font configuration fonts.
  96       * It is populated by :
  97       * - awtfontpath entries in the fontconfig.properties
  98       * - parent directories of "core" fonts used in the fontconfig.properties
  99       * - looking up font dirs in the xFontDirsMap where the key is a fontID
 100       *   (cut down version of the XLFD read from the font configuration file).
 101       * This set is nulled out after use to free heap space.
 102       */
 103      private static HashSet<String> fontConfigDirs = null;
 104 
 105     /* These maps are used on Linux where we reference the Lucida oblique
 106      * fonts in fontconfig files even though they aren't in the standard
 107      * font directory. This explicitly remaps the XLFDs for these to the
 108      * correct base font. This is needed to prevent composite fonts from
 109      * defaulting to the Lucida Sans which is a bad substitute for the
 110      * monospaced Lucida Sans Typewriter. Also these maps prevent the
 111      * JRE from doing wasted work at start up.
 112      */
 113     HashMap<String, String> oblmap = null;
 114 
 115 
 116     /*
 117      * Used to eliminate redundant work. When a font directory is
 118      * registered it added to this list. Subsequent registrations for the
 119      * same directory can then be skipped by checking this Map.
 120      * Access to this map is not synchronised here since creation
 121      * of the singleton GE instance is already synchronised and that is
 122      * the only code path that accesses this map.
 123      */
 124      private static HashMap registeredDirs = new HashMap();
 125 
 126      /* Array of directories to be added to the X11 font path.
 127       * Used by static method called from Toolkits which use X11 fonts.
 128       * Specifically this means MToolkit
 129       */
 130      private static String[] fontdirs = null;
 131 
 132     private static String[] defaultPlatformFont = null;
 133 
 134     private FontConfigManager fcManager = null;
 135 
 136     public static X11FontManager getInstance() {
 137         return (X11FontManager) SunFontManager.getInstance();
 138     }
 139 
 140     /**
 141      * Takes family name property in the following format:
 142      * "-linotype-helvetica-medium-r-normal-sans-*-%d-*-*-p-*-iso8859-1"
 143      * and returns the name of the corresponding physical font.
 144      * This code is used to resolve font configuration fonts, and expects


 166         fileName = super.getFileNameFromPlatformName(platName);
 167         if (fileName != null) {
 168             if (isHeadless() && fileName.startsWith("-")) {
 169                 /* if it's headless, no xlfd should be used */
 170                     return null;
 171             }
 172             if (fileName.startsWith("/")) {
 173                 /* If a path is assigned in the font configuration file,
 174                  * it is required that the config file also specify using the
 175                  * new awtfontpath key the X11 font directories
 176                  * which must be added to the X11 font path to support
 177                  * AWT access to that font. For that reason we no longer
 178                  * have code here to add the parent directory to the list
 179                  * of font config dirs, since the parent directory may not
 180                  * be sufficient if fonts are symbolically linked to a
 181                  * different directory.
 182                  *
 183                  * Add this XLFD (platform name) to the list of known
 184                  * ones for this file.
 185                  */
 186                 Vector xVal = (Vector) xlfdMap.get(fileName);
 187                 if (xVal == null) {
 188                     /* Try to be robust on Linux distros which move fonts
 189                      * around by verifying that the fileName represents a
 190                      * file that exists.  If it doesn't, set it to null
 191                      * to trigger a search.
 192                      */
 193                     if (getFontConfiguration().needToSearchForFile(fileName)) {
 194                         fileName = null;
 195                     }
 196                     if (fileName != null) {
 197                         xVal = new Vector();
 198                         xVal.add(platName);
 199                         xlfdMap.put(fileName, xVal);
 200                     }
 201                 } else {
 202                     if (!xVal.contains(platName)) {
 203                         xVal.add(platName);
 204                     }
 205                 }
 206             }
 207             if (fileName != null) {
 208                 fontNameMap.put(fontID, fileName);
 209                 return fileName;
 210             }
 211         }
 212 
 213         if (fontID != null) {
 214             fileName = (String)fontNameMap.get(fontID);
 215             /* On Linux check for the Lucida Oblique fonts */
 216             if (fileName == null && FontUtilities.isLinux && !isOpenJDK()) {
 217                 if (oblmap == null) {
 218                     initObliqueLucidaFontMap();
 219                 }
 220                 String oblkey = getObliqueLucidaFontID(fontID);
 221                 if (oblkey != null) {
 222                     fileName = oblmap.get(oblkey);
 223                 }
 224             }
 225             if (fontPath == null &&
 226                 (fileName == null || !fileName.startsWith("/"))) {
 227                 if (FontUtilities.debugFonts()) {
 228                     FontUtilities.getLogger()
 229                           .warning("** Registering all font paths because " +
 230                                    "can't find file for " + platName);
 231                 }
 232                 fontPath = getPlatformFontPath(noType1Font);
 233                 registerFontDirs(fontPath);
 234                 if (FontUtilities.debugFonts()) {
 235                     FontUtilities.getLogger()
 236                             .warning("** Finished registering all font paths");
 237                 }
 238                 fileName = (String)fontNameMap.get(fontID);
 239             }
 240             if (fileName == null && !isHeadless()) {
 241                 /* Query X11 directly to see if this font is available
 242                  * as a native font.
 243                  */
 244                 fileName = getX11FontName(platName);
 245             }
 246             if (fileName == null) {
 247                 fontID = switchFontIDForName(platName);
 248                 fileName = (String)fontNameMap.get(fontID);
 249             }
 250             if (fileName != null) {
 251                 fontNameMap.put(fontID, fileName);
 252             }
 253         }
 254         return fileName;
 255     }
 256 
 257     @Override
 258     protected String[] getNativeNames(String fontFileName,
 259             String platformName) {
 260         Vector nativeNames;
 261         if ((nativeNames=(Vector)xlfdMap.get(fontFileName))==null) {
 262             if (platformName == null) {
 263                 return null;
 264             } else {
 265                 /* back-stop so that at least the name used in the
 266                  * font configuration file is known as a native name
 267                  */
 268                 String []natNames = new String[1];
 269                 natNames[0] = platformName;
 270                 return natNames;
 271             }
 272         } else {
 273             int len = nativeNames.size();
 274             return (String[])nativeNames.toArray(new String[len]);
 275         }
 276     }
 277 
 278     /* NOTE: this method needs to be executed in a privileged context.
 279      * The superclass constructor which is the primary caller of
 280      * this method executes entirely in such a context. Additionally
 281      * the loadFonts() method does too. So all should be well.
 282 
 283      */
 284     @Override
 285     protected void registerFontDir(String path) {
 286         /* fonts.dir file format looks like :-
 287          * 47
 288          * Arial.ttf -monotype-arial-regular-r-normal--0-0-0-0-p-0-iso8859-1
 289          * Arial-Bold.ttf -monotype-arial-bold-r-normal--0-0-0-0-p-0-iso8859-1
 290          * ...
 291          */
 292         if (FontUtilities.debugFonts()) {
 293             FontUtilities.getLogger().info("ParseFontDir " + path);
 294         }


 349                                 if (ttype != StreamTokenizer.TT_EOL) {
 350                                     break;
 351                                 }
 352                                 continue;
 353                             }
 354                             String fileName = st.sval.substring(0, breakPos);
 355                             /* TurboLinux 8.0 uses some additional syntax to
 356                              * indicate algorithmic styling values.
 357                              * Ignore ':' separated files at the beginning
 358                              * of the fileName
 359                              */
 360                             int lastColon = fileName.lastIndexOf(':');
 361                             if (lastColon > 0) {
 362                                 if (lastColon+1 >= fileName.length()) {
 363                                     continue;
 364                                 }
 365                                 fileName = fileName.substring(lastColon+1);
 366                             }
 367                             String fontPart = st.sval.substring(breakPos+1);
 368                             String fontID = specificFontIDForName(fontPart);
 369                             String sVal = (String) fontNameMap.get(fontID);
 370 
 371                             if (FontUtilities.debugFonts()) {
 372                                 PlatformLogger logger = FontUtilities.getLogger();
 373                                 logger.info("file=" + fileName +
 374                                             " xlfd=" + fontPart);
 375                                 logger.info("fontID=" + fontID +
 376                                             " sVal=" + sVal);
 377                             }
 378                             String fullPath = null;
 379                             try {
 380                                 File file = new File(path,fileName);
 381                                 /* we may have a resolved symbolic link
 382                                  * this becomes important for an xlfd we
 383                                  * still need to know the location it was
 384                                  * found to update the X server font path
 385                                  * for use by AWT heavyweights - and when 2D
 386                                  * wants to use the native rasteriser.
 387                                  */
 388                                 if (xFontDirsMap == null) {
 389                                     xFontDirsMap = new HashMap();
 390                                 }
 391                                 xFontDirsMap.put(fontID, path);
 392                                 fullPath = file.getCanonicalPath();
 393                             } catch (IOException e) {
 394                                 fullPath = path + File.separator + fileName;
 395                             }
 396                             Vector xVal = (Vector) xlfdMap.get(fullPath);
 397                             if (FontUtilities.debugFonts()) {
 398                                 FontUtilities.getLogger()
 399                                       .info("fullPath=" + fullPath +
 400                                             " xVal=" + xVal);
 401                             }
 402                             if ((xVal == null || !xVal.contains(fontPart)) &&
 403                                 (sVal == null) || !sVal.startsWith("/")) {
 404                                 if (FontUtilities.debugFonts()) {
 405                                     FontUtilities.getLogger()
 406                                           .info("Map fontID:"+fontID +
 407                                                 "to file:" + fullPath);
 408                                 }
 409                                 fontNameMap.put(fontID, fullPath);
 410                                 if (xVal == null) {
 411                                     xVal = new Vector();
 412                                     xlfdMap.put (fullPath, xVal);
 413                                 }
 414                                 xVal.add(fontPart);
 415                             }
 416 
 417                             ttype = st.nextToken();
 418                             if (ttype != StreamTokenizer.TT_EOL) {
 419                                 break;
 420                             }
 421                         }
 422                     }
 423                 }
 424                 fr.close();
 425             }
 426         } catch (IOException ioe1) {
 427         } finally {
 428             if (fr != null) {
 429                 try {
 430                     fr.close();
 431                 }  catch (IOException ioe2) {
 432                 }
 433             }
 434         }
 435     }
 436 
 437     @Override
 438     public void loadFonts() {
 439         super.loadFonts();
 440         /* These maps are greatly expanded during a loadFonts but
 441          * can be reset to their initial state afterwards.
 442          * Since preferLocaleFonts() and preferProportionalFonts() will
 443          * trigger a partial repopulating from the FontConfiguration
 444          * it has to be the inital (empty) state for the latter two, not
 445          * simply nulling out.
 446          * xFontDirsMap is a special case in that the implementation
 447          * will typically not ever need to initialise it so it can be null.
 448          */
 449         xFontDirsMap = null;
 450         xlfdMap = new HashMap(1);
 451         fontNameMap = new HashMap(1);
 452     }
 453 
 454     private String getObliqueLucidaFontID(String fontID) {
 455         if (fontID.startsWith("-lucidasans-medium-i-normal") ||
 456             fontID.startsWith("-lucidasans-bold-i-normal") ||
 457             fontID.startsWith("-lucidatypewriter-medium-i-normal") ||
 458             fontID.startsWith("-lucidatypewriter-bold-i-normal")) {
 459             return fontID.substring(0, fontID.indexOf("-i-"));
 460         } else {
 461             return null;
 462         }
 463     }
 464 
 465     private static String getX11FontName(String platName) {
 466         String xlfd = platName.replaceAll("%d", "*");
 467         if (NativeFont.fontExists(xlfd)) {
 468             return xlfd;
 469         } else {
 470             return null;
 471         }


 562         }
 563         StringBuffer sb =
 564             new StringBuffer(name.substring(hPos[FAMILY_NAME_FIELD-1],
 565                                             hPos[SLANT_FIELD-1]+1));
 566         sb.append(slant);
 567         sb.append(name.substring(hPos[SLANT_FIELD],
 568                                  hPos[SETWIDTH_NAME_FIELD]+1));
 569         sb.append(registry);
 570         sb.append(name.substring(hPos[CHARSET_ENCODING_FIELD-1]));
 571         String retval = sb.toString().toLowerCase (Locale.ENGLISH);
 572         return retval;
 573     }
 574 
 575     /**
 576      * Returns the face name for the given XLFD.
 577      */
 578     public String getFileNameFromXLFD(String name) {
 579         String fileName = null;
 580         String fontID = specificFontIDForName(name);
 581         if (fontID != null) {
 582             fileName = (String)fontNameMap.get(fontID);
 583             if (fileName == null) {
 584                 fontID = switchFontIDForName(name);
 585                 fileName = (String)fontNameMap.get(fontID);
 586             }
 587             if (fileName == null) {
 588                 fileName = getDefaultFontFile();
 589             }
 590         }
 591         return fileName;
 592     }
 593 
 594     /* Register just the paths, (it doesn't register the fonts).
 595      * If a font configuration file has specified a baseFontPath
 596      * fontPath is just those directories, unless on usage we
 597      * find it doesn't contain what we need for the logical fonts.
 598      * Otherwise, we register all the paths on Solaris, because
 599      * the fontPath we have here is the complete one from
 600      * parsing /var/sadm/install/contents, not just
 601      * what's on the X font path (may be this should be
 602      * changed).
 603      * But for now what it means is that if we didn't do
 604      * this then if the font weren't listed anywhere on the
 605      * less complete font path we'd trigger loadFonts which


 668     // and add it to the X font path (if display is local)
 669     // Here we make use of an already built map of xlfds to font locations
 670     // to add the font location to the set of those required to build the
 671     // x font path needed by AWT.
 672     // These are added to the x font path later.
 673     // All this is necessary because on Solaris the font.dir directories
 674     // may contain not real font files, but symbolic links to the actual
 675     // location but that location is not suitable for the x font path, since
 676     // it probably doesn't have a font.dir at all and certainly not one
 677     // with the required encodings
 678     // If the fontconfiguration file is properly set up so that all fonts
 679     // are mapped to files then we will never trigger initialising
 680     // xFontDirsMap (it will be null). In this case the awtfontpath entries
 681     // must specify all the X11 directories needed by AWT.
 682     @Override
 683     protected void addFontToPlatformFontPath(String platformName) {
 684         // Lazily initialize fontConfigDirs.
 685         getPlatformFontPathFromFontConfig();
 686         if (xFontDirsMap != null) {
 687             String fontID = specificFontIDForName(platformName);
 688             String dirName = (String)xFontDirsMap.get(fontID);
 689             if (dirName != null) {
 690                 fontConfigDirs.add(dirName);
 691             }
 692         }
 693         return;
 694     }
 695 
 696     private void getPlatformFontPathFromFontConfig() {
 697         if (fontConfigDirs == null) {
 698             fontConfigDirs = getFontConfiguration().getAWTFontPathSet();
 699             if (FontUtilities.debugFonts() && fontConfigDirs != null) {
 700                 String[] names = fontConfigDirs.toArray(new String[0]);
 701                 for (int i=0;i<names.length;i++) {
 702                     FontUtilities.getLogger().info("awtfontpath : " + names[i]);
 703                 }
 704             }
 705         }
 706     }
 707 
 708     @Override




  42     private static final int POINT_SIZE_FIELD = 8;
  43     private static final int RESOLUTION_X_FIELD = 9;
  44     private static final int RESOLUTION_Y_FIELD = 10;
  45     private static final int SPACING_FIELD = 11;
  46     private static final int AVERAGE_WIDTH_FIELD = 12;
  47     private static final int CHARSET_REGISTRY_FIELD = 13;
  48     private static final int CHARSET_ENCODING_FIELD = 14;
  49 
  50     /*
  51      * fontNameMap is a map from a fontID (which is a substring of an XLFD like
  52      * "-monotype-arial-bold-r-normal-iso8859-7")
  53      * to font file path like
  54      * /usr/openwin/lib/locale/iso_8859_7/X11/fonts/TrueType/ArialBoldItalic.ttf
  55      * It's used in a couple of methods like
  56      * getFileNameFomPlatformName(..) to help locate the font file.
  57      * We use this substring of a full XLFD because the font configuration files
  58      * define the XLFDs in a way that's easier to make into a request.
  59      * E.g., the -0-0-0-0-p-0- reported by X is -*-%d-*-*-p-*- in the font
  60      * configuration files. We need to remove that part for comparisons.
  61      */
  62     private static Map<String, String> fontNameMap = new HashMap<>();
  63 
  64     /*
  65      * xlfdMap is a map from a platform path like
  66      * /usr/openwin/lib/locale/ja/X11/fonts/TT/HG-GothicB.ttf to an XLFD like
  67      * "-ricoh-hg gothic b-medium-r-normal--0-0-0-0-m-0-jisx0201.1976-0"
  68      * Because there may be multiple native names, because the font is used
  69      * to support multiple X encodings for example, the value of an entry in
  70      * this map is always a vector where we store all the native names.
  71      * For fonts which we don't understand the key isn't a pathname, its
  72      * the full XLFD string like :-
  73      * "-ricoh-hg gothic b-medium-r-normal--0-0-0-0-m-0-jisx0201.1976-0"
  74      */
  75     private static Map<String, Vector<String>> xlfdMap = new HashMap<>();
  76 
  77     /* xFontDirsMap is also a map from a font ID to a font filepath.
  78      * The difference from fontNameMap is just that it does not have
  79      * resolved symbolic links. Normally this is not interesting except
  80      * that we need to know the directory in which a font was found to
  81      * add it to the X font server path, since although the files may
  82      * be linked, the fonts.dir is different and specific to the encoding
  83      * handled by that directory. This map is nulled out after use to free
  84      * heap space. If the optimal path is taken, such that all fonts in
  85      * font configuration files are referenced by filename, then the font
  86      * dir can be directly derived as its parent directory.
  87      * If a font is used by two XLFDs, each corresponding to a different
  88      * X11 font directory, then precautions must be taken to include both
  89      * directories.
  90      */
  91      private static Map<String, String> xFontDirsMap;
  92 
  93      /*
  94       * This is the set of font directories needed to be on the X font path
  95       * to enable AWT heavyweights to find all of the font configuration fonts.
  96       * It is populated by :
  97       * - awtfontpath entries in the fontconfig.properties
  98       * - parent directories of "core" fonts used in the fontconfig.properties
  99       * - looking up font dirs in the xFontDirsMap where the key is a fontID
 100       *   (cut down version of the XLFD read from the font configuration file).
 101       * This set is nulled out after use to free heap space.
 102       */
 103      private static HashSet<String> fontConfigDirs = null;
 104 
 105     /* These maps are used on Linux where we reference the Lucida oblique
 106      * fonts in fontconfig files even though they aren't in the standard
 107      * font directory. This explicitly remaps the XLFDs for these to the
 108      * correct base font. This is needed to prevent composite fonts from
 109      * defaulting to the Lucida Sans which is a bad substitute for the
 110      * monospaced Lucida Sans Typewriter. Also these maps prevent the
 111      * JRE from doing wasted work at start up.
 112      */
 113     HashMap<String, String> oblmap = null;
 114 
 115 
 116     /*
 117      * Used to eliminate redundant work. When a font directory is
 118      * registered it added to this list. Subsequent registrations for the
 119      * same directory can then be skipped by checking this Map.
 120      * Access to this map is not synchronised here since creation
 121      * of the singleton GE instance is already synchronised and that is
 122      * the only code path that accesses this map.
 123      */
 124      private static HashMap<String, Object> registeredDirs = new HashMap<>();
 125 
 126      /* Array of directories to be added to the X11 font path.
 127       * Used by static method called from Toolkits which use X11 fonts.
 128       * Specifically this means MToolkit
 129       */
 130      private static String[] fontdirs = null;
 131 
 132     private static String[] defaultPlatformFont = null;
 133 
 134     private FontConfigManager fcManager = null;
 135 
 136     public static X11FontManager getInstance() {
 137         return (X11FontManager) SunFontManager.getInstance();
 138     }
 139 
 140     /**
 141      * Takes family name property in the following format:
 142      * "-linotype-helvetica-medium-r-normal-sans-*-%d-*-*-p-*-iso8859-1"
 143      * and returns the name of the corresponding physical font.
 144      * This code is used to resolve font configuration fonts, and expects


 166         fileName = super.getFileNameFromPlatformName(platName);
 167         if (fileName != null) {
 168             if (isHeadless() && fileName.startsWith("-")) {
 169                 /* if it's headless, no xlfd should be used */
 170                     return null;
 171             }
 172             if (fileName.startsWith("/")) {
 173                 /* If a path is assigned in the font configuration file,
 174                  * it is required that the config file also specify using the
 175                  * new awtfontpath key the X11 font directories
 176                  * which must be added to the X11 font path to support
 177                  * AWT access to that font. For that reason we no longer
 178                  * have code here to add the parent directory to the list
 179                  * of font config dirs, since the parent directory may not
 180                  * be sufficient if fonts are symbolically linked to a
 181                  * different directory.
 182                  *
 183                  * Add this XLFD (platform name) to the list of known
 184                  * ones for this file.
 185                  */
 186                 Vector<String> xVal = xlfdMap.get(fileName);
 187                 if (xVal == null) {
 188                     /* Try to be robust on Linux distros which move fonts
 189                      * around by verifying that the fileName represents a
 190                      * file that exists.  If it doesn't, set it to null
 191                      * to trigger a search.
 192                      */
 193                     if (getFontConfiguration().needToSearchForFile(fileName)) {
 194                         fileName = null;
 195                     }
 196                     if (fileName != null) {
 197                         xVal = new Vector<>();
 198                         xVal.add(platName);
 199                         xlfdMap.put(fileName, xVal);
 200                     }
 201                 } else {
 202                     if (!xVal.contains(platName)) {
 203                         xVal.add(platName);
 204                     }
 205                 }
 206             }
 207             if (fileName != null) {
 208                 fontNameMap.put(fontID, fileName);
 209                 return fileName;
 210             }
 211         }
 212 
 213         if (fontID != null) {
 214             fileName = fontNameMap.get(fontID);
 215             /* On Linux check for the Lucida Oblique fonts */
 216             if (fileName == null && FontUtilities.isLinux && !isOpenJDK()) {
 217                 if (oblmap == null) {
 218                     initObliqueLucidaFontMap();
 219                 }
 220                 String oblkey = getObliqueLucidaFontID(fontID);
 221                 if (oblkey != null) {
 222                     fileName = oblmap.get(oblkey);
 223                 }
 224             }
 225             if (fontPath == null &&
 226                 (fileName == null || !fileName.startsWith("/"))) {
 227                 if (FontUtilities.debugFonts()) {
 228                     FontUtilities.getLogger()
 229                           .warning("** Registering all font paths because " +
 230                                    "can't find file for " + platName);
 231                 }
 232                 fontPath = getPlatformFontPath(noType1Font);
 233                 registerFontDirs(fontPath);
 234                 if (FontUtilities.debugFonts()) {
 235                     FontUtilities.getLogger()
 236                             .warning("** Finished registering all font paths");
 237                 }
 238                 fileName = fontNameMap.get(fontID);
 239             }
 240             if (fileName == null && !isHeadless()) {
 241                 /* Query X11 directly to see if this font is available
 242                  * as a native font.
 243                  */
 244                 fileName = getX11FontName(platName);
 245             }
 246             if (fileName == null) {
 247                 fontID = switchFontIDForName(platName);
 248                 fileName = fontNameMap.get(fontID);
 249             }
 250             if (fileName != null) {
 251                 fontNameMap.put(fontID, fileName);
 252             }
 253         }
 254         return fileName;
 255     }
 256 
 257     @Override
 258     protected String[] getNativeNames(String fontFileName,
 259             String platformName) {
 260         Vector<String> nativeNames;
 261         if ((nativeNames=xlfdMap.get(fontFileName))==null) {
 262             if (platformName == null) {
 263                 return null;
 264             } else {
 265                 /* back-stop so that at least the name used in the
 266                  * font configuration file is known as a native name
 267                  */
 268                 String []natNames = new String[1];
 269                 natNames[0] = platformName;
 270                 return natNames;
 271             }
 272         } else {
 273             int len = nativeNames.size();
 274             return nativeNames.toArray(new String[len]);
 275         }
 276     }
 277 
 278     /* NOTE: this method needs to be executed in a privileged context.
 279      * The superclass constructor which is the primary caller of
 280      * this method executes entirely in such a context. Additionally
 281      * the loadFonts() method does too. So all should be well.
 282 
 283      */
 284     @Override
 285     protected void registerFontDir(String path) {
 286         /* fonts.dir file format looks like :-
 287          * 47
 288          * Arial.ttf -monotype-arial-regular-r-normal--0-0-0-0-p-0-iso8859-1
 289          * Arial-Bold.ttf -monotype-arial-bold-r-normal--0-0-0-0-p-0-iso8859-1
 290          * ...
 291          */
 292         if (FontUtilities.debugFonts()) {
 293             FontUtilities.getLogger().info("ParseFontDir " + path);
 294         }


 349                                 if (ttype != StreamTokenizer.TT_EOL) {
 350                                     break;
 351                                 }
 352                                 continue;
 353                             }
 354                             String fileName = st.sval.substring(0, breakPos);
 355                             /* TurboLinux 8.0 uses some additional syntax to
 356                              * indicate algorithmic styling values.
 357                              * Ignore ':' separated files at the beginning
 358                              * of the fileName
 359                              */
 360                             int lastColon = fileName.lastIndexOf(':');
 361                             if (lastColon > 0) {
 362                                 if (lastColon+1 >= fileName.length()) {
 363                                     continue;
 364                                 }
 365                                 fileName = fileName.substring(lastColon+1);
 366                             }
 367                             String fontPart = st.sval.substring(breakPos+1);
 368                             String fontID = specificFontIDForName(fontPart);
 369                             String sVal = fontNameMap.get(fontID);
 370 
 371                             if (FontUtilities.debugFonts()) {
 372                                 PlatformLogger logger = FontUtilities.getLogger();
 373                                 logger.info("file=" + fileName +
 374                                             " xlfd=" + fontPart);
 375                                 logger.info("fontID=" + fontID +
 376                                             " sVal=" + sVal);
 377                             }
 378                             String fullPath = null;
 379                             try {
 380                                 File file = new File(path,fileName);
 381                                 /* we may have a resolved symbolic link
 382                                  * this becomes important for an xlfd we
 383                                  * still need to know the location it was
 384                                  * found to update the X server font path
 385                                  * for use by AWT heavyweights - and when 2D
 386                                  * wants to use the native rasteriser.
 387                                  */
 388                                 if (xFontDirsMap == null) {
 389                                     xFontDirsMap = new HashMap<>();
 390                                 }
 391                                 xFontDirsMap.put(fontID, path);
 392                                 fullPath = file.getCanonicalPath();
 393                             } catch (IOException e) {
 394                                 fullPath = path + File.separator + fileName;
 395                             }
 396                             Vector<String> xVal = xlfdMap.get(fullPath);
 397                             if (FontUtilities.debugFonts()) {
 398                                 FontUtilities.getLogger()
 399                                       .info("fullPath=" + fullPath +
 400                                             " xVal=" + xVal);
 401                             }
 402                             if ((xVal == null || !xVal.contains(fontPart)) &&
 403                                 (sVal == null) || !sVal.startsWith("/")) {
 404                                 if (FontUtilities.debugFonts()) {
 405                                     FontUtilities.getLogger()
 406                                           .info("Map fontID:"+fontID +
 407                                                 "to file:" + fullPath);
 408                                 }
 409                                 fontNameMap.put(fontID, fullPath);
 410                                 if (xVal == null) {
 411                                     xVal = new Vector<>();
 412                                     xlfdMap.put (fullPath, xVal);
 413                                 }
 414                                 xVal.add(fontPart);
 415                             }
 416 
 417                             ttype = st.nextToken();
 418                             if (ttype != StreamTokenizer.TT_EOL) {
 419                                 break;
 420                             }
 421                         }
 422                     }
 423                 }
 424                 fr.close();
 425             }
 426         } catch (IOException ioe1) {
 427         } finally {
 428             if (fr != null) {
 429                 try {
 430                     fr.close();
 431                 }  catch (IOException ioe2) {
 432                 }
 433             }
 434         }
 435     }
 436 
 437     @Override
 438     public void loadFonts() {
 439         super.loadFonts();
 440         /* These maps are greatly expanded during a loadFonts but
 441          * can be reset to their initial state afterwards.
 442          * Since preferLocaleFonts() and preferProportionalFonts() will
 443          * trigger a partial repopulating from the FontConfiguration
 444          * it has to be the inital (empty) state for the latter two, not
 445          * simply nulling out.
 446          * xFontDirsMap is a special case in that the implementation
 447          * will typically not ever need to initialise it so it can be null.
 448          */
 449         xFontDirsMap = null;
 450         xlfdMap = new HashMap<>(1);
 451         fontNameMap = new HashMap<>(1);
 452     }
 453 
 454     private String getObliqueLucidaFontID(String fontID) {
 455         if (fontID.startsWith("-lucidasans-medium-i-normal") ||
 456             fontID.startsWith("-lucidasans-bold-i-normal") ||
 457             fontID.startsWith("-lucidatypewriter-medium-i-normal") ||
 458             fontID.startsWith("-lucidatypewriter-bold-i-normal")) {
 459             return fontID.substring(0, fontID.indexOf("-i-"));
 460         } else {
 461             return null;
 462         }
 463     }
 464 
 465     private static String getX11FontName(String platName) {
 466         String xlfd = platName.replaceAll("%d", "*");
 467         if (NativeFont.fontExists(xlfd)) {
 468             return xlfd;
 469         } else {
 470             return null;
 471         }


 562         }
 563         StringBuffer sb =
 564             new StringBuffer(name.substring(hPos[FAMILY_NAME_FIELD-1],
 565                                             hPos[SLANT_FIELD-1]+1));
 566         sb.append(slant);
 567         sb.append(name.substring(hPos[SLANT_FIELD],
 568                                  hPos[SETWIDTH_NAME_FIELD]+1));
 569         sb.append(registry);
 570         sb.append(name.substring(hPos[CHARSET_ENCODING_FIELD-1]));
 571         String retval = sb.toString().toLowerCase (Locale.ENGLISH);
 572         return retval;
 573     }
 574 
 575     /**
 576      * Returns the face name for the given XLFD.
 577      */
 578     public String getFileNameFromXLFD(String name) {
 579         String fileName = null;
 580         String fontID = specificFontIDForName(name);
 581         if (fontID != null) {
 582             fileName = fontNameMap.get(fontID);
 583             if (fileName == null) {
 584                 fontID = switchFontIDForName(name);
 585                 fileName = fontNameMap.get(fontID);
 586             }
 587             if (fileName == null) {
 588                 fileName = getDefaultFontFile();
 589             }
 590         }
 591         return fileName;
 592     }
 593 
 594     /* Register just the paths, (it doesn't register the fonts).
 595      * If a font configuration file has specified a baseFontPath
 596      * fontPath is just those directories, unless on usage we
 597      * find it doesn't contain what we need for the logical fonts.
 598      * Otherwise, we register all the paths on Solaris, because
 599      * the fontPath we have here is the complete one from
 600      * parsing /var/sadm/install/contents, not just
 601      * what's on the X font path (may be this should be
 602      * changed).
 603      * But for now what it means is that if we didn't do
 604      * this then if the font weren't listed anywhere on the
 605      * less complete font path we'd trigger loadFonts which


 668     // and add it to the X font path (if display is local)
 669     // Here we make use of an already built map of xlfds to font locations
 670     // to add the font location to the set of those required to build the
 671     // x font path needed by AWT.
 672     // These are added to the x font path later.
 673     // All this is necessary because on Solaris the font.dir directories
 674     // may contain not real font files, but symbolic links to the actual
 675     // location but that location is not suitable for the x font path, since
 676     // it probably doesn't have a font.dir at all and certainly not one
 677     // with the required encodings
 678     // If the fontconfiguration file is properly set up so that all fonts
 679     // are mapped to files then we will never trigger initialising
 680     // xFontDirsMap (it will be null). In this case the awtfontpath entries
 681     // must specify all the X11 directories needed by AWT.
 682     @Override
 683     protected void addFontToPlatformFontPath(String platformName) {
 684         // Lazily initialize fontConfigDirs.
 685         getPlatformFontPathFromFontConfig();
 686         if (xFontDirsMap != null) {
 687             String fontID = specificFontIDForName(platformName);
 688             String dirName = xFontDirsMap.get(fontID);
 689             if (dirName != null) {
 690                 fontConfigDirs.add(dirName);
 691             }
 692         }
 693         return;
 694     }
 695 
 696     private void getPlatformFontPathFromFontConfig() {
 697         if (fontConfigDirs == null) {
 698             fontConfigDirs = getFontConfiguration().getAWTFontPathSet();
 699             if (FontUtilities.debugFonts() && fontConfigDirs != null) {
 700                 String[] names = fontConfigDirs.toArray(new String[0]);
 701                 for (int i=0;i<names.length;i++) {
 702                     FontUtilities.getLogger().info("awtfontpath : " + names[i]);
 703                 }
 704             }
 705         }
 706     }
 707 
 708     @Override