jdk/src/share/classes/sun/java2d/SunGraphicsEnvironment.java
changeset 3928 be186a33df9b
parent 1724 a22a286aa16f
child 3938 ef327bd847c0
equal deleted inserted replaced
3927:d717df90e151 3928:be186a33df9b
    62 import sun.awt.FontConfiguration;
    62 import sun.awt.FontConfiguration;
    63 import sun.awt.SunDisplayChanger;
    63 import sun.awt.SunDisplayChanger;
    64 import sun.font.CompositeFontDescriptor;
    64 import sun.font.CompositeFontDescriptor;
    65 import sun.font.Font2D;
    65 import sun.font.Font2D;
    66 import sun.font.FontManager;
    66 import sun.font.FontManager;
       
    67 import sun.font.FontManagerFactory;
       
    68 import sun.font.FontManagerForSGE;
    67 import sun.font.NativeFont;
    69 import sun.font.NativeFont;
    68 
    70 
    69 /**
    71 /**
    70  * This is an implementation of a GraphicsEnvironment object for the
    72  * This is an implementation of a GraphicsEnvironment object for the
    71  * default local GraphicsEnvironment.
    73  * default local GraphicsEnvironment.
    72  *
    74  *
    73  * @see GraphicsDevice
    75  * @see GraphicsDevice
    74  * @see GraphicsConfiguration
    76  * @see GraphicsConfiguration
    75  */
    77  */
    76 
       
    77 public abstract class SunGraphicsEnvironment extends GraphicsEnvironment
    78 public abstract class SunGraphicsEnvironment extends GraphicsEnvironment
    78     implements FontSupport, DisplayChangedListener {
    79     implements DisplayChangedListener {
    79 
    80 
    80     public static boolean isLinux;
       
    81     public static boolean isSolaris;
       
    82     public static boolean isOpenSolaris;
    81     public static boolean isOpenSolaris;
    83     public static boolean isWindows;
       
    84     public static boolean noType1Font;
       
    85     private static Font defaultFont;
    82     private static Font defaultFont;
    86     private static String defaultFontFileName;
       
    87     private static String defaultFontName;
       
    88     public static final String lucidaFontName = "Lucida Sans Regular";
       
    89     public static final String lucidaFileName = "LucidaSansRegular.ttf";
       
    90     public static boolean debugFonts = false;
       
    91     protected static Logger logger = null;
    83     protected static Logger logger = null;
    92     private static ArrayList badFonts;
       
    93     public static String jreLibDirName;
       
    94     public static String jreFontDirName;
       
    95     private static HashSet<String> missingFontFiles = null;
       
    96 
       
    97     private FontConfiguration fontConfig;
       
    98 
       
    99     /* fontPath is the location of all fonts on the system, excluding the
       
   100      * JRE's own font directory but including any path specified using the
       
   101      * sun.java2d.fontpath property. Together with that property,  it is
       
   102      * initialised by the getPlatformFontPath() method
       
   103      * This call must be followed by a call to registerFontDirs(fontPath)
       
   104      * once any extra debugging path has been appended.
       
   105      */
       
   106     protected String fontPath;
       
   107 
       
   108     /* discoveredAllFonts is set to true when all fonts on the font path are
       
   109      * discovered. This usually also implies opening, validating and
       
   110      * registering, but an implementation may be optimized to avold this.
       
   111      * So see also "loadedAllFontFiles"
       
   112      */
       
   113     private boolean discoveredAllFonts = false;
       
   114 
       
   115     /* loadedAllFontFiles is set to true when all fonts on the font path are
       
   116      * actually opened, validated and registered. This always implies
       
   117      * discoveredAllFonts is true.
       
   118      */
       
   119     private boolean loadedAllFontFiles = false;
       
   120 
       
   121     protected HashSet registeredFontFiles = new HashSet();
       
   122     public static String eudcFontFileName; /* Initialised only on windows */
       
   123 
       
   124     private static boolean isOpenJDK;
       
   125     /**
       
   126      * A few things in Java 2D code are different in OpenJDK,
       
   127      * so need a way to tell which implementation this is.
       
   128      * The absence of Lucida Sans Regular is the simplest way for now.
       
   129      */
       
   130     public static boolean isOpenJDK() {
       
   131         return isOpenJDK;
       
   132     }
       
   133 
       
   134     static {
       
   135         java.security.AccessController.doPrivileged(
       
   136                                     new java.security.PrivilegedAction() {
       
   137             public Object run() {
       
   138 
       
   139                 jreLibDirName = System.getProperty("java.home","") +
       
   140                     File.separator + "lib";
       
   141                 jreFontDirName = jreLibDirName + File.separator + "fonts";
       
   142                 File lucidaFile =
       
   143                     new File(jreFontDirName + File.separator + lucidaFileName);
       
   144                 isOpenJDK = !lucidaFile.exists();
       
   145 
       
   146                 String debugLevel =
       
   147                     System.getProperty("sun.java2d.debugfonts");
       
   148 
       
   149                 if (debugLevel != null && !debugLevel.equals("false")) {
       
   150                     debugFonts = true;
       
   151                     logger = Logger.getLogger("sun.java2d");
       
   152                     if (debugLevel.equals("warning")) {
       
   153                         logger.setLevel(Level.WARNING);
       
   154                     } else if (debugLevel.equals("severe")) {
       
   155                         logger.setLevel(Level.SEVERE);
       
   156                     }
       
   157                 }
       
   158                 return null;
       
   159             }
       
   160         });
       
   161     };
       
   162 
    84 
   163     public SunGraphicsEnvironment() {
    85     public SunGraphicsEnvironment() {
   164         java.security.AccessController.doPrivileged(
    86         java.security.AccessController.doPrivileged(
   165                                     new java.security.PrivilegedAction() {
    87                                     new java.security.PrivilegedAction() {
   166             public Object run() {
    88             public Object run() {
   167                 String osName = System.getProperty("os.name");
       
   168                 if ("Linux".equals(osName)) {
       
   169                     isLinux = true;
       
   170                 } else if ("SunOS".equals(osName)) {
       
   171                     isSolaris = true;
       
   172                     String version = System.getProperty("os.version", "0.0");
    89                     String version = System.getProperty("os.version", "0.0");
   173                     try {
    90                     try {
   174                         float ver = Float.parseFloat(version);
    91                         float ver = Float.parseFloat(version);
   175                         if (ver > 5.10f) {
    92                         if (ver > 5.10f) {
   176                             File f = new File("/etc/release");
    93                             File f = new File("/etc/release");
   184                             }
   101                             }
   185                             fis.close();
   102                             fis.close();
   186                         }
   103                         }
   187                     } catch (Exception e) {
   104                     } catch (Exception e) {
   188                     }
   105                     }
   189                 } else if ("Windows".equals(osName)) {
       
   190                     isWindows = true;
       
   191                 }
       
   192 
       
   193                 noType1Font = "true".
       
   194                     equals(System.getProperty("sun.java2d.noType1Font"));
       
   195 
       
   196                 if (!isOpenJDK()) {
       
   197                     defaultFontName = lucidaFontName;
       
   198                     if (useAbsoluteFontFileNames()) {
       
   199                         defaultFontFileName =
       
   200                             jreFontDirName + File.separator + lucidaFileName;
       
   201                     } else {
       
   202                         defaultFontFileName = lucidaFileName;
       
   203                     }
       
   204                 }
       
   205 
       
   206                 File badFontFile =
       
   207                     new File(jreFontDirName + File.separator + "badfonts.txt");
       
   208                 if (badFontFile.exists()) {
       
   209                     FileInputStream fis = null;
       
   210                     try {
       
   211                         badFonts = new ArrayList();
       
   212                         fis = new FileInputStream(badFontFile);
       
   213                         InputStreamReader isr = new InputStreamReader(fis);
       
   214                         BufferedReader br = new BufferedReader(isr);
       
   215                         while (true) {
       
   216                             String name = br.readLine();
       
   217                             if (name == null) {
       
   218                                 break;
       
   219                             } else {
       
   220                                 if (debugFonts) {
       
   221                                     logger.warning("read bad font: " + name);
       
   222                                 }
       
   223                                 badFonts.add(name);
       
   224                             }
       
   225                         }
       
   226                     } catch (IOException e) {
       
   227                         try {
       
   228                             if (fis != null) {
       
   229                                 fis.close();
       
   230                             }
       
   231                         } catch (IOException ioe) {
       
   232                         }
       
   233                     }
       
   234                 }
       
   235 
       
   236                 /* Here we get the fonts in jre/lib/fonts and register them
       
   237                  * so they are always available and preferred over other fonts.
       
   238                  * This needs to be registered before the composite fonts as
       
   239                  * otherwise some native font that corresponds may be found
       
   240                  * as we don't have a way to handle two fonts of the same
       
   241                  * name, so the JRE one must be the first one registered.
       
   242                  * Pass "true" to registerFonts method as on-screen these
       
   243                  * JRE fonts always go through the T2K rasteriser.
       
   244                  */
       
   245                 if (isLinux) {
       
   246                     /* Linux font configuration uses these fonts */
       
   247                     registerFontDir(jreFontDirName);
       
   248                 }
       
   249                 registerFontsInDir(jreFontDirName, true, Font2D.JRE_RANK,
       
   250                                    true, false);
       
   251 
       
   252                 /* Register the JRE fonts so that the native platform can
       
   253                  * access them. This is used only on Windows so that when
       
   254                  * printing the printer driver can access the fonts.
       
   255                  */
       
   256                 registerJREFontsWithPlatform(jreFontDirName);
       
   257 
       
   258                 /* Create the font configuration and get any font path
       
   259                  * that might be specified.
       
   260                  */
       
   261                 fontConfig = createFontConfiguration();
       
   262                 if (isOpenJDK()) {
       
   263                     String[] fontInfo = FontManager.getDefaultPlatformFont();
       
   264                     defaultFontName = fontInfo[0];
       
   265                     defaultFontFileName = fontInfo[1];
       
   266                 }
       
   267                 getPlatformFontPathFromFontConfig();
       
   268 
       
   269                 String extraFontPath = fontConfig.getExtraFontPath();
       
   270 
       
   271                 /* In prior releases the debugging font path replaced
       
   272                  * all normally located font directories except for the
       
   273                  * JRE fonts dir. This directory is still always located and
       
   274                  * placed at the head of the path but as an augmentation
       
   275                  * to the previous behaviour the
       
   276                  * changes below allow you to additionally append to
       
   277                  * the font path by starting with append: or prepend by
       
   278                  * starting with a prepend: sign. Eg: to append
       
   279                  * -Dsun.java2d.fontpath=append:/usr/local/myfonts
       
   280                  * and to prepend
       
   281                  * -Dsun.java2d.fontpath=prepend:/usr/local/myfonts Disp
       
   282                  *
       
   283                  * If there is an appendedfontpath it in the font configuration
       
   284                  * it is used instead of searching the system for dirs.
       
   285                  * The behaviour of append and prepend is then similar
       
   286                  * to the normal case. ie it goes after what
       
   287                  * you prepend and * before what you append. If the
       
   288                  * sun.java2d.fontpath property is used, but it
       
   289                  * neither the append or prepend syntaxes is used then as
       
   290                  * except for the JRE dir the path is replaced and it is
       
   291                  * up to you to make sure that all the right directories
       
   292                  * are located. This is platform and locale-specific so
       
   293                  * its almost impossible to get right, so it should be
       
   294                  * used with caution.
       
   295                  */
       
   296                 boolean prependToPath = false;
       
   297                 boolean appendToPath = false;
       
   298                 String dbgFontPath = System.getProperty("sun.java2d.fontpath");
       
   299 
       
   300                 if (dbgFontPath != null) {
       
   301                     if (dbgFontPath.startsWith("prepend:")) {
       
   302                         prependToPath = true;
       
   303                         dbgFontPath =
       
   304                             dbgFontPath.substring("prepend:".length());
       
   305                     } else if (dbgFontPath.startsWith("append:")) {
       
   306                         appendToPath = true;
       
   307                         dbgFontPath =
       
   308                             dbgFontPath.substring("append:".length());
       
   309                     }
       
   310                 }
       
   311 
       
   312                 if (debugFonts) {
       
   313                     logger.info("JRE font directory: " + jreFontDirName);
       
   314                     logger.info("Extra font path: " + extraFontPath);
       
   315                     logger.info("Debug font path: " + dbgFontPath);
       
   316                 }
       
   317 
       
   318                 if (dbgFontPath != null) {
       
   319                     /* In debugging mode we register all the paths
       
   320                      * Caution: this is a very expensive call on Solaris:-
       
   321                      */
       
   322                     fontPath = getPlatformFontPath(noType1Font);
       
   323 
       
   324                     if (extraFontPath != null) {
       
   325                         fontPath =
       
   326                             extraFontPath + File.pathSeparator + fontPath;
       
   327                     }
       
   328                     if (appendToPath) {
       
   329                         fontPath = fontPath + File.pathSeparator + dbgFontPath;
       
   330                     } else if (prependToPath) {
       
   331                         fontPath = dbgFontPath + File.pathSeparator + fontPath;
       
   332                     } else {
       
   333                         fontPath = dbgFontPath;
       
   334                     }
       
   335                     registerFontDirs(fontPath);
       
   336                 } else if (extraFontPath != null) {
       
   337                     /* If the font configuration contains an "appendedfontpath"
       
   338                      * entry, it is interpreted as a set of locations that
       
   339                      * should always be registered.
       
   340                      * It may be additional to locations normally found for
       
   341                      * that place, or it may be locations that need to have
       
   342                      * all their paths registered to locate all the needed
       
   343                      * platform names.
       
   344                      * This is typically when the same .TTF file is referenced
       
   345                      * from multiple font.dir files and all of these must be
       
   346                      * read to find all the native (XLFD) names for the font,
       
   347                      * so that X11 font APIs can be used for as many code
       
   348                      * points as possible.
       
   349                      */
       
   350                     registerFontDirs(extraFontPath);
       
   351                 }
       
   352 
       
   353                 /* On Solaris, we need to register the Japanese TrueType
       
   354                  * directory so that we can find the corresponding bitmap
       
   355                  * fonts. This could be done by listing the directory in
       
   356                  * the font configuration file, but we don't want to
       
   357                  * confuse users with this quirk. There are no bitmap fonts
       
   358                  * for other writing systems that correspond to TrueType
       
   359                  * fonts and have matching XLFDs. We need to register the
       
   360                  * bitmap fonts only in environments where they're on the
       
   361                  * X font path, i.e., in the Japanese locale.
       
   362                  * Note that if the X Toolkit is in use the font path isn't
       
   363                  * set up by JDK, but users of a JA locale should have it
       
   364                  * set up already by their login environment.
       
   365                  */
       
   366                 if (isSolaris && Locale.JAPAN.equals(Locale.getDefault())) {
       
   367                     registerFontDir("/usr/openwin/lib/locale/ja/X11/fonts/TT");
       
   368                 }
       
   369 
       
   370                 initCompositeFonts(fontConfig, null);
       
   371 
   106 
   372                 /* Establish the default font to be used by SG2D etc */
   107                 /* Establish the default font to be used by SG2D etc */
   373                 defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
   108                 defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
   374 
   109 
   375                 return null;
   110                 return null;
   393             screens = ret;
   128             screens = ret;
   394         }
   129         }
   395         return ret;
   130         return ret;
   396     }
   131     }
   397 
   132 
       
   133     /**
       
   134      * Returns the number of screen devices of this graphics environment.
       
   135      *
       
   136      * @return the number of screen devices of this graphics environment
       
   137      */
   398     protected abstract int getNumScreens();
   138     protected abstract int getNumScreens();
       
   139 
       
   140     /**
       
   141      * Create and return the screen device with the specified number. The
       
   142      * device with number <code>0</code> will be the default device (returned
       
   143      * by {@link #getDefaultScreenDevice()}.
       
   144      *
       
   145      * @param screennum the number of the screen to create
       
   146      *
       
   147      * @return the created screen device
       
   148      */
   399     protected abstract GraphicsDevice makeScreenDevice(int screennum);
   149     protected abstract GraphicsDevice makeScreenDevice(int screennum);
   400 
   150 
   401     /**
   151     /**
   402      * Returns the default screen graphics device.
   152      * Returns the default screen graphics device.
   403      */
   153      */
   416         }
   166         }
   417         SurfaceData sd = SurfaceData.getPrimarySurfaceData(img);
   167         SurfaceData sd = SurfaceData.getPrimarySurfaceData(img);
   418         return new SunGraphics2D(sd, Color.white, Color.black, defaultFont);
   168         return new SunGraphics2D(sd, Color.white, Color.black, defaultFont);
   419     }
   169     }
   420 
   170 
   421     /* A call to this method should be followed by a call to
   171     private static FontManagerForSGE getFontManagerForSGE() {
   422      * registerFontDirs(..)
   172         FontManager fm = FontManagerFactory.getInstance();
   423      */
   173         return (FontManagerForSGE) fm;
   424     protected String getPlatformFontPath(boolean noType1Font) {
   174     }
   425         if (fontPath == null) {
       
   426             fontPath = FontManager.getFontPath(noType1Font);
       
   427         }
       
   428         return fontPath;
       
   429     }
       
   430 
       
   431     private String[] platformFontDirs;
       
   432     /**
       
   433      * Get all directories which contain installed fonts.
       
   434      */
       
   435     public String[] getPlatformFontDirs() {
       
   436         if (platformFontDirs == null) {
       
   437             String path = getPlatformFontPath(noType1Font);
       
   438             StringTokenizer parser =
       
   439                 new StringTokenizer(path, File.pathSeparator);;
       
   440             ArrayList<String> pathList = new ArrayList<String>();
       
   441             try {
       
   442                 while (parser.hasMoreTokens()) {
       
   443                     pathList.add(parser.nextToken());
       
   444                 }
       
   445             } catch (NoSuchElementException e) {
       
   446             }
       
   447             platformFontDirs = pathList.toArray(new String[0]);
       
   448         }
       
   449         return platformFontDirs;
       
   450     }
       
   451 
       
   452     /**
       
   453      * Whether registerFontFile expects absolute or relative
       
   454      * font file names.
       
   455      */
       
   456     protected boolean useAbsoluteFontFileNames() {
       
   457         return true;
       
   458     }
       
   459 
       
   460     /**
       
   461      * Returns file name for default font, either absolute
       
   462      * or relative as needed by registerFontFile.
       
   463      */
       
   464     public String getDefaultFontFile() {
       
   465         return defaultFontFileName;
       
   466     }
       
   467 
       
   468     /**
       
   469      * Returns face name for default font, or null if
       
   470      * no face names are used for CompositeFontDescriptors
       
   471      * for this platform.
       
   472      */
       
   473     public String getDefaultFontFaceName() {
       
   474         return defaultFontName;
       
   475     }
       
   476 
       
   477     public void loadFonts() {
       
   478         if (discoveredAllFonts) {
       
   479             return;
       
   480         }
       
   481         /* Use lock specific to the font system */
       
   482         synchronized (lucidaFontName) {
       
   483             if (debugFonts) {
       
   484                 Thread.dumpStack();
       
   485                 logger.info("SunGraphicsEnvironment.loadFonts() called");
       
   486             }
       
   487             FontManager.initialiseDeferredFonts();
       
   488 
       
   489             java.security.AccessController.doPrivileged(
       
   490                                     new java.security.PrivilegedAction() {
       
   491                 public Object run() {
       
   492                     if (fontPath == null) {
       
   493                         fontPath = getPlatformFontPath(noType1Font);
       
   494                         registerFontDirs(fontPath);
       
   495                     }
       
   496                     if (fontPath != null) {
       
   497                         // this will find all fonts including those already
       
   498                         // registered. But we have checks in place to prevent
       
   499                         // double registration.
       
   500                         if (!FontManager.gotFontsFromPlatform()) {
       
   501                             registerFontsOnPath(fontPath, false,
       
   502                                                 Font2D.UNKNOWN_RANK,
       
   503                                                 false, true);
       
   504                             loadedAllFontFiles = true;
       
   505                         }
       
   506                     }
       
   507                     FontManager.registerOtherFontFiles(registeredFontFiles);
       
   508                     discoveredAllFonts = true;
       
   509                     return null;
       
   510                 }
       
   511             });
       
   512         }
       
   513     }
       
   514 
       
   515 
       
   516     public void loadFontFiles() {
       
   517         loadFonts();
       
   518         if (loadedAllFontFiles) {
       
   519             return;
       
   520         }
       
   521         /* Use lock specific to the font system */
       
   522         synchronized (lucidaFontName) {
       
   523             if (debugFonts) {
       
   524                 Thread.dumpStack();
       
   525                 logger.info("loadAllFontFiles() called");
       
   526             }
       
   527             java.security.AccessController.doPrivileged(
       
   528                                     new java.security.PrivilegedAction() {
       
   529                 public Object run() {
       
   530                     if (fontPath == null) {
       
   531                         fontPath = getPlatformFontPath(noType1Font);
       
   532                     }
       
   533                     if (fontPath != null) {
       
   534                         // this will find all fonts including those already
       
   535                         // registered. But we have checks in place to prevent
       
   536                         // double registration.
       
   537                         registerFontsOnPath(fontPath, false,
       
   538                                             Font2D.UNKNOWN_RANK,
       
   539                                             false, true);
       
   540                     }
       
   541                     loadedAllFontFiles = true;
       
   542                     return null;
       
   543                 }
       
   544             });
       
   545         }
       
   546     }
       
   547 
       
   548     /*
       
   549      * This is for use only within getAllFonts().
       
   550      * Fonts listed in the fontconfig files for windows were all
       
   551      * on the "deferred" initialisation list. They were registered
       
   552      * either in the course of the application, or in the call to
       
   553      * loadFonts() within getAllFonts(). The fontconfig file specifies
       
   554      * the names of the fonts using the English names. If there's a
       
   555      * different name in the execution locale, then the platform will
       
   556      * report that, and we will construct the font with both names, and
       
   557      * thereby enumerate it twice. This happens for Japanese fonts listed
       
   558      * in the windows fontconfig, when run in the JA locale. The solution
       
   559      * is to rely (in this case) on the platform's font->file mapping to
       
   560      * determine that this name corresponds to a file we already registered.
       
   561      * This works because
       
   562      * - we know when we get here all deferred fonts are already initialised
       
   563      * - when we register a font file, we register all fonts in it.
       
   564      * - we know the fontconfig fonts are all in the windows registry
       
   565      */
       
   566     private boolean isNameForRegisteredFile(String fontName) {
       
   567         String fileName = FontManager.getFileNameForFontName(fontName);
       
   568         if (fileName == null) {
       
   569             return false;
       
   570         }
       
   571         return registeredFontFiles.contains(fileName);
       
   572     }
       
   573 
       
   574     private Font[] allFonts;
       
   575 
       
   576     /**
       
   577      * Returns all fonts installed in this environment.
       
   578      */
       
   579     public Font[] getAllInstalledFonts() {
       
   580         if (allFonts == null) {
       
   581             loadFonts();
       
   582             TreeMap fontMapNames = new TreeMap();
       
   583             /* warning: the number of composite fonts could change dynamically
       
   584              * if applications are allowed to create them. "allfonts" could
       
   585              * then be stale.
       
   586              */
       
   587 
       
   588             Font2D[] allfonts = FontManager.getRegisteredFonts();
       
   589             for (int i=0; i < allfonts.length; i++) {
       
   590                 if (!(allfonts[i] instanceof NativeFont)) {
       
   591                     fontMapNames.put(allfonts[i].getFontName(null),
       
   592                                      allfonts[i]);
       
   593                 }
       
   594             }
       
   595 
       
   596             String[] platformNames =  FontManager.getFontNamesFromPlatform();
       
   597             if (platformNames != null) {
       
   598                 for (int i=0; i<platformNames.length; i++) {
       
   599                     if (!isNameForRegisteredFile(platformNames[i])) {
       
   600                         fontMapNames.put(platformNames[i], null);
       
   601                     }
       
   602                 }
       
   603             }
       
   604 
       
   605             String[] fontNames = null;
       
   606             if (fontMapNames.size() > 0) {
       
   607                 fontNames = new String[fontMapNames.size()];
       
   608                 Object [] keyNames = fontMapNames.keySet().toArray();
       
   609                 for (int i=0; i < keyNames.length; i++) {
       
   610                     fontNames[i] = (String)keyNames[i];
       
   611                 }
       
   612             }
       
   613             Font[] fonts = new Font[fontNames.length];
       
   614             for (int i=0; i < fontNames.length; i++) {
       
   615                 fonts[i] = new Font(fontNames[i], Font.PLAIN, 1);
       
   616                 Font2D f2d = (Font2D)fontMapNames.get(fontNames[i]);
       
   617                 if (f2d  != null) {
       
   618                     FontManager.setFont2D(fonts[i], f2d.handle);
       
   619                 }
       
   620             }
       
   621             allFonts = fonts;
       
   622         }
       
   623 
       
   624         Font []copyFonts = new Font[allFonts.length];
       
   625         System.arraycopy(allFonts, 0, copyFonts, 0, allFonts.length);
       
   626         return copyFonts;
       
   627     }
       
   628 
       
   629      /**
   175      /**
   630      * Returns all fonts available in this environment.
   176      * Returns all fonts available in this environment.
   631      */
   177      */
   632     public Font[] getAllFonts() {
   178     public Font[] getAllFonts() {
   633         Font[] installedFonts = getAllInstalledFonts();
   179         FontManagerForSGE fm = getFontManagerForSGE();
   634         Font[] created = FontManager.getCreatedFonts();
   180         Font[] installedFonts = fm.getAllInstalledFonts();
       
   181         Font[] created = fm.getCreatedFonts();
   635         if (created == null || created.length == 0) {
   182         if (created == null || created.length == 0) {
   636             return installedFonts;
   183             return installedFonts;
   637         } else {
   184         } else {
   638             int newlen = installedFonts.length + created.length;
   185             int newlen = installedFonts.length + created.length;
   639             Font [] fonts = java.util.Arrays.copyOf(installedFonts, newlen);
   186             Font [] fonts = java.util.Arrays.copyOf(installedFonts, newlen);
   641                              installedFonts.length, created.length);
   188                              installedFonts.length, created.length);
   642             return fonts;
   189             return fonts;
   643         }
   190         }
   644     }
   191     }
   645 
   192 
   646     /**
       
   647      * Default locale can be changed but we need to know the initial locale
       
   648      * as that is what is used by native code. Changing Java default locale
       
   649      * doesn't affect that.
       
   650      * Returns the locale in use when using native code to communicate
       
   651      * with platform APIs. On windows this is known as the "system" locale,
       
   652      * and it is usually the same as the platform locale, but not always,
       
   653      * so this method also checks an implementation property used only
       
   654      * on windows and uses that if set.
       
   655      */
       
   656     private static Locale systemLocale = null;
       
   657     public static Locale getSystemStartupLocale() {
       
   658         if (systemLocale == null) {
       
   659             systemLocale = (Locale)
       
   660                 java.security.AccessController.doPrivileged(
       
   661                                     new java.security.PrivilegedAction() {
       
   662             public Object run() {
       
   663                 /* On windows the system locale may be different than the
       
   664                  * user locale. This is an unsupported configuration, but
       
   665                  * in that case we want to return a dummy locale that will
       
   666                  * never cause a match in the usage of this API. This is
       
   667                  * important because Windows documents that the family
       
   668                  * names of fonts are enumerated using the language of
       
   669                  * the system locale. BY returning a dummy locale in that
       
   670                  * case we do not use the platform API which would not
       
   671                  * return us the names we want.
       
   672                  */
       
   673                 String fileEncoding = System.getProperty("file.encoding", "");
       
   674                 String sysEncoding = System.getProperty("sun.jnu.encoding");
       
   675                 if (sysEncoding != null && !sysEncoding.equals(fileEncoding)) {
       
   676                     return Locale.ROOT;
       
   677                 }
       
   678 
       
   679                 String language = System.getProperty("user.language", "en");
       
   680                 String country  = System.getProperty("user.country","");
       
   681                 String variant  = System.getProperty("user.variant","");
       
   682                 return new Locale(language, country, variant);
       
   683             }
       
   684         });
       
   685         }
       
   686         return systemLocale;
       
   687     }
       
   688 
       
   689     /* Really we need only the JRE fonts family names, but there's little
       
   690      * overhead in doing this the easy way by adding all the currently
       
   691      * known fonts.
       
   692      */
       
   693     protected void getJREFontFamilyNames(TreeMap<String,String> familyNames,
       
   694                                          Locale requestedLocale) {
       
   695         FontManager.registerDeferredJREFonts(jreFontDirName);
       
   696         Font2D[] physicalfonts = FontManager.getPhysicalFonts();
       
   697         for (int i=0; i < physicalfonts.length; i++) {
       
   698             if (!(physicalfonts[i] instanceof NativeFont)) {
       
   699                 String name =
       
   700                     physicalfonts[i].getFamilyName(requestedLocale);
       
   701                 familyNames.put(name.toLowerCase(requestedLocale), name);
       
   702             }
       
   703         }
       
   704     }
       
   705 
       
   706     private String[] allFamilies; // cache for default locale only
       
   707     private Locale lastDefaultLocale;
       
   708 
       
   709     public String[] getInstalledFontFamilyNames(Locale requestedLocale) {
       
   710         if (requestedLocale == null) {
       
   711             requestedLocale = Locale.getDefault();
       
   712         }
       
   713         if (allFamilies != null && lastDefaultLocale != null &&
       
   714             requestedLocale.equals(lastDefaultLocale)) {
       
   715                 String[] copyFamilies = new String[allFamilies.length];
       
   716                 System.arraycopy(allFamilies, 0, copyFamilies,
       
   717                                  0, allFamilies.length);
       
   718                 return copyFamilies;
       
   719         }
       
   720 
       
   721         TreeMap<String,String> familyNames = new TreeMap<String,String>();
       
   722         //  these names are always there and aren't localised
       
   723         String str;
       
   724         str = Font.SERIF;         familyNames.put(str.toLowerCase(), str);
       
   725         str = Font.SANS_SERIF;    familyNames.put(str.toLowerCase(), str);
       
   726         str = Font.MONOSPACED;    familyNames.put(str.toLowerCase(), str);
       
   727         str = Font.DIALOG;        familyNames.put(str.toLowerCase(), str);
       
   728         str = Font.DIALOG_INPUT;  familyNames.put(str.toLowerCase(), str);
       
   729 
       
   730         /* Platform APIs may be used to get the set of available family
       
   731          * names for the current default locale so long as it is the same
       
   732          * as the start-up system locale, rather than loading all fonts.
       
   733          */
       
   734         if (requestedLocale.equals(getSystemStartupLocale()) &&
       
   735             FontManager.getFamilyNamesFromPlatform(familyNames,
       
   736                                                     requestedLocale)) {
       
   737             /* Augment platform names with JRE font family names */
       
   738             getJREFontFamilyNames(familyNames, requestedLocale);
       
   739         } else {
       
   740             loadFontFiles();
       
   741             Font2D[] physicalfonts = FontManager.getPhysicalFonts();
       
   742             for (int i=0; i < physicalfonts.length; i++) {
       
   743                 if (!(physicalfonts[i] instanceof NativeFont)) {
       
   744                     String name =
       
   745                         physicalfonts[i].getFamilyName(requestedLocale);
       
   746                     familyNames.put(name.toLowerCase(requestedLocale), name);
       
   747                 }
       
   748             }
       
   749         }
       
   750 
       
   751         String[] retval =  new String[familyNames.size()];
       
   752         Object [] keyNames = familyNames.keySet().toArray();
       
   753         for (int i=0; i < keyNames.length; i++) {
       
   754             retval[i] = (String)familyNames.get(keyNames[i]);
       
   755         }
       
   756         if (requestedLocale.equals(Locale.getDefault())) {
       
   757             lastDefaultLocale = requestedLocale;
       
   758             allFamilies = new String[retval.length];
       
   759             System.arraycopy(retval, 0, allFamilies, 0, allFamilies.length);
       
   760         }
       
   761         return retval;
       
   762     }
       
   763 
       
   764     public String[] getAvailableFontFamilyNames(Locale requestedLocale) {
   193     public String[] getAvailableFontFamilyNames(Locale requestedLocale) {
   765         String[] installed = getInstalledFontFamilyNames(requestedLocale);
   194         FontManagerForSGE fm = getFontManagerForSGE();
       
   195         String[] installed = fm.getInstalledFontFamilyNames(requestedLocale);
   766         /* Use a new TreeMap as used in getInstalledFontFamilyNames
   196         /* Use a new TreeMap as used in getInstalledFontFamilyNames
   767          * and insert all the keys in lower case, so that the sort order
   197          * and insert all the keys in lower case, so that the sort order
   768          * is the same as the installed families. This preserves historical
   198          * is the same as the installed families. This preserves historical
   769          * behaviour and inserts new families in the right place.
   199          * behaviour and inserts new families in the right place.
   770          * It would have been marginally more efficient to directly obtain
   200          * It would have been marginally more efficient to directly obtain
   771          * the tree map and just insert new entries, but not so much as
   201          * the tree map and just insert new entries, but not so much as
   772          * to justify the extra internal interface.
   202          * to justify the extra internal interface.
   773          */
   203          */
   774         TreeMap<String, String> map = FontManager.getCreatedFontFamilyNames();
   204         TreeMap<String, String> map = fm.getCreatedFontFamilyNames();
   775         if (map == null || map.size() == 0) {
   205         if (map == null || map.size() == 0) {
   776             return installed;
   206             return installed;
   777         } else {
   207         } else {
   778             for (int i=0; i<installed.length; i++) {
   208             for (int i=0; i<installed.length; i++) {
   779                 map.put(installed[i].toLowerCase(requestedLocale),
   209                 map.put(installed[i].toLowerCase(requestedLocale),
   791     public String[] getAvailableFontFamilyNames() {
   221     public String[] getAvailableFontFamilyNames() {
   792         return getAvailableFontFamilyNames(Locale.getDefault());
   222         return getAvailableFontFamilyNames(Locale.getDefault());
   793     }
   223     }
   794 
   224 
   795     /**
   225     /**
   796      * Returns a file name for the physical font represented by this platform
       
   797      * font name. The default implementation tries to obtain the file name
       
   798      * from the font configuration.
       
   799      * Subclasses may override to provide information from other sources.
       
   800      */
       
   801     protected String getFileNameFromPlatformName(String platformFontName) {
       
   802         return fontConfig.getFileNameFromPlatformName(platformFontName);
       
   803     }
       
   804 
       
   805     public static class TTFilter implements FilenameFilter {
       
   806         public boolean accept(File dir,String name) {
       
   807             /* all conveniently have the same suffix length */
       
   808             int offset = name.length()-4;
       
   809             if (offset <= 0) { /* must be at least A.ttf */
       
   810                 return false;
       
   811             } else {
       
   812                 return(name.startsWith(".ttf", offset) ||
       
   813                        name.startsWith(".TTF", offset) ||
       
   814                        name.startsWith(".ttc", offset) ||
       
   815                        name.startsWith(".TTC", offset) ||
       
   816                        name.startsWith(".otf", offset) ||
       
   817                        name.startsWith(".OTF", offset));
       
   818             }
       
   819         }
       
   820     }
       
   821 
       
   822     public static class T1Filter implements FilenameFilter {
       
   823         public boolean accept(File dir,String name) {
       
   824             if (noType1Font) {
       
   825                 return false;
       
   826             }
       
   827             /* all conveniently have the same suffix length */
       
   828             int offset = name.length()-4;
       
   829             if (offset <= 0) { /* must be at least A.pfa */
       
   830                 return false;
       
   831             } else {
       
   832                 return(name.startsWith(".pfa", offset) ||
       
   833                        name.startsWith(".pfb", offset) ||
       
   834                        name.startsWith(".PFA", offset) ||
       
   835                        name.startsWith(".PFB", offset));
       
   836             }
       
   837         }
       
   838     }
       
   839 
       
   840     public static class TTorT1Filter implements FilenameFilter {
       
   841          public boolean accept(File dir, String name) {
       
   842              return SunGraphicsEnvironment.ttFilter.accept(dir, name) ||
       
   843                  SunGraphicsEnvironment.t1Filter.accept(dir, name);
       
   844          }
       
   845     }
       
   846 
       
   847     /* No need to keep consing up new instances - reuse a singleton.
       
   848      * The trade-off is that these objects don't get GC'd.
       
   849      */
       
   850     public static final TTFilter ttFilter = new TTFilter();
       
   851     public static final T1Filter t1Filter = new T1Filter();
       
   852 
       
   853     /* The majority of the register functions in this class are
       
   854      * registering platform fonts in the JRE's font maps.
       
   855      * The next one is opposite in function as it registers the JRE
       
   856      * fonts as platform fonts. If subsequent to calling this
       
   857      * your implementation enumerates platform fonts in a way that
       
   858      * would return these fonts too you may get duplicates.
       
   859      * This function is primarily used to install the JRE fonts
       
   860      * so that the native platform can access them.
       
   861      * It is intended to be overridden by platform subclasses
       
   862      * Currently minimal use is made of this as generally
       
   863      * Java 2D doesn't need the platform to be able to
       
   864      * use its fonts and platforms which already have matching
       
   865      * fonts registered (possibly even from other different JRE
       
   866      * versions) generally can't be guaranteed to use the
       
   867      * one registered by this JRE version in response to
       
   868      * requests from this JRE.
       
   869      */
       
   870     protected void registerJREFontsWithPlatform(String pathName) {
       
   871         return;
       
   872     }
       
   873 
       
   874     /* Called from FontManager - has Solaris specific implementation */
       
   875     public void register1dot0Fonts() {
       
   876         java.security.AccessController.doPrivileged(
       
   877                             new java.security.PrivilegedAction() {
       
   878             public Object run() {
       
   879                 String type1Dir = "/usr/openwin/lib/X11/fonts/Type1";
       
   880                 registerFontsInDir(type1Dir, true, Font2D.TYPE1_RANK,
       
   881                                    false, false);
       
   882                 return null;
       
   883             }
       
   884         });
       
   885     }
       
   886 
       
   887     protected void registerFontDirs(String pathName) {
       
   888         return;
       
   889     }
       
   890 
       
   891     /* Called to register fall back fonts */
       
   892     public void registerFontsInDir(String dirName) {
       
   893         registerFontsInDir(dirName, true, Font2D.JRE_RANK, true, false);
       
   894     }
       
   895 
       
   896     private void registerFontsInDir(String dirName, boolean useJavaRasterizer,
       
   897                                     int fontRank,
       
   898                                     boolean defer, boolean resolveSymLinks) {
       
   899         File pathFile = new File(dirName);
       
   900         addDirFonts(dirName, pathFile, ttFilter,
       
   901                     FontManager.FONTFORMAT_TRUETYPE, useJavaRasterizer,
       
   902                     fontRank==Font2D.UNKNOWN_RANK ?
       
   903                     Font2D.TTF_RANK : fontRank,
       
   904                     defer, resolveSymLinks);
       
   905         addDirFonts(dirName, pathFile, t1Filter,
       
   906                     FontManager.FONTFORMAT_TYPE1, useJavaRasterizer,
       
   907                     fontRank==Font2D.UNKNOWN_RANK ?
       
   908                     Font2D.TYPE1_RANK : fontRank,
       
   909                     defer, resolveSymLinks);
       
   910     }
       
   911 
       
   912     private void registerFontsOnPath(String pathName,
       
   913                                      boolean useJavaRasterizer, int fontRank,
       
   914                                      boolean defer, boolean resolveSymLinks) {
       
   915 
       
   916         StringTokenizer parser = new StringTokenizer(pathName,
       
   917                                                      File.pathSeparator);
       
   918         try {
       
   919             while (parser.hasMoreTokens()) {
       
   920                 registerFontsInDir(parser.nextToken(),
       
   921                                    useJavaRasterizer, fontRank,
       
   922                                    defer, resolveSymLinks);
       
   923             }
       
   924         } catch (NoSuchElementException e) {
       
   925         }
       
   926     }
       
   927 
       
   928     protected void registerFontFile(String fontFileName, String[] nativeNames,
       
   929                                     int fontRank, boolean defer) {
       
   930         // REMIND: case compare depends on platform
       
   931         if (registeredFontFiles.contains(fontFileName)) {
       
   932             return;
       
   933         }
       
   934         int fontFormat;
       
   935         if (ttFilter.accept(null, fontFileName)) {
       
   936             fontFormat = FontManager.FONTFORMAT_TRUETYPE;
       
   937         } else if (t1Filter.accept(null, fontFileName)) {
       
   938             fontFormat = FontManager.FONTFORMAT_TYPE1;
       
   939         } else {
       
   940             fontFormat = FontManager.FONTFORMAT_NATIVE;
       
   941         }
       
   942         registeredFontFiles.add(fontFileName);
       
   943         if (defer) {
       
   944             FontManager.registerDeferredFont(fontFileName,
       
   945                                              fontFileName, nativeNames,
       
   946                                              fontFormat, false, fontRank);
       
   947         } else {
       
   948             FontManager.registerFontFile(fontFileName, nativeNames,
       
   949                                          fontFormat, false, fontRank);
       
   950         }
       
   951     }
       
   952 
       
   953     protected void registerFontDir(String path) {
       
   954     }
       
   955 
       
   956     protected String[] getNativeNames(String fontFileName,
       
   957                                       String platformName) {
       
   958         return null;
       
   959     }
       
   960 
       
   961     /*
       
   962      * helper function for registerFonts
       
   963      */
       
   964     private void addDirFonts(String dirName, File dirFile,
       
   965                              FilenameFilter filter,
       
   966                              int fontFormat, boolean useJavaRasterizer,
       
   967                              int fontRank,
       
   968                              boolean defer, boolean resolveSymLinks) {
       
   969         String[] ls = dirFile.list(filter);
       
   970         if (ls == null || ls.length == 0) {
       
   971             return;
       
   972         }
       
   973         String[] fontNames = new String[ls.length];
       
   974         String[][] nativeNames = new String[ls.length][];
       
   975         int fontCount = 0;
       
   976 
       
   977         for (int i=0; i < ls.length; i++ ) {
       
   978             File theFile = new File(dirFile, ls[i]);
       
   979             String fullName = null;
       
   980             if (resolveSymLinks) {
       
   981                 try {
       
   982                     fullName = theFile.getCanonicalPath();
       
   983                 } catch (IOException e) {
       
   984                 }
       
   985             }
       
   986             if (fullName == null) {
       
   987                 fullName = dirName + File.separator + ls[i];
       
   988             }
       
   989 
       
   990             // REMIND: case compare depends on platform
       
   991             if (registeredFontFiles.contains(fullName)) {
       
   992                 continue;
       
   993             }
       
   994 
       
   995             if (badFonts != null && badFonts.contains(fullName)) {
       
   996                 if (debugFonts) {
       
   997                     logger.warning("skip bad font " + fullName);
       
   998                 }
       
   999                 continue; // skip this font file.
       
  1000             }
       
  1001 
       
  1002             registeredFontFiles.add(fullName);
       
  1003 
       
  1004             if (debugFonts && logger.isLoggable(Level.INFO)) {
       
  1005                 String message = "Registering font " + fullName;
       
  1006                 String[] natNames = getNativeNames(fullName, null);
       
  1007                 if (natNames == null) {
       
  1008                     message += " with no native name";
       
  1009                 } else {
       
  1010                     message += " with native name(s) " + natNames[0];
       
  1011                     for (int nn = 1; nn < natNames.length; nn++) {
       
  1012                         message += ", " + natNames[nn];
       
  1013                     }
       
  1014                 }
       
  1015                 logger.info(message);
       
  1016             }
       
  1017             fontNames[fontCount] = fullName;
       
  1018             nativeNames[fontCount++] = getNativeNames(fullName, null);
       
  1019         }
       
  1020         FontManager.registerFonts(fontNames, nativeNames, fontCount,
       
  1021                                   fontFormat, useJavaRasterizer, fontRank,
       
  1022                                   defer);
       
  1023         return;
       
  1024     }
       
  1025 
       
  1026     /*
       
  1027      * A GE may verify whether a font file used in a fontconfiguration
       
  1028      * exists. If it doesn't then either we may substitute the default
       
  1029      * font, or perhaps elide it altogether from the composite font.
       
  1030      * This makes some sense on windows where the font file is only
       
  1031      * likely to be in one place. But on other OSes, eg Linux, the file
       
  1032      * can move around depending. So there we probably don't want to assume
       
  1033      * its missing and so won't add it to this list.
       
  1034      * If this list - missingFontFiles - is non-null then the composite
       
  1035      * font initialisation logic tests to see if a font file is in that
       
  1036      * set.
       
  1037      * Only one thread should be able to add to this set so we don't
       
  1038      * synchronize.
       
  1039      */
       
  1040     protected void addToMissingFontFileList(String fileName) {
       
  1041         if (missingFontFiles == null) {
       
  1042             missingFontFiles = new HashSet<String>();
       
  1043         }
       
  1044         missingFontFiles.add(fileName);
       
  1045     }
       
  1046 
       
  1047     /**
       
  1048      * Creates this environment's FontConfiguration.
       
  1049      */
       
  1050     protected abstract FontConfiguration createFontConfiguration();
       
  1051 
       
  1052     public abstract FontConfiguration
       
  1053         createFontConfiguration(boolean preferLocaleFonts,
       
  1054                                 boolean preferPropFonts);
       
  1055 
       
  1056     /*
       
  1057      * This method asks the font configuration API for all platform names
       
  1058      * used as components of composite/logical fonts and iterates over these
       
  1059      * looking up their corresponding file name and registers these fonts.
       
  1060      * It also ensures that the fonts are accessible via platform APIs.
       
  1061      * The composites themselves are then registered.
       
  1062      */
       
  1063     private void
       
  1064         initCompositeFonts(FontConfiguration fontConfig,
       
  1065                            ConcurrentHashMap<String, Font2D>  altNameCache) {
       
  1066 
       
  1067         int numCoreFonts = fontConfig.getNumberCoreFonts();
       
  1068         String[] fcFonts = fontConfig.getPlatformFontNames();
       
  1069         for (int f=0; f<fcFonts.length; f++) {
       
  1070             String platformFontName = fcFonts[f];
       
  1071             String fontFileName =
       
  1072                 getFileNameFromPlatformName(platformFontName);
       
  1073             String[] nativeNames = null;
       
  1074             if (fontFileName == null || fontFileName.equals(platformFontName)){
       
  1075                 /* No file located, so register using the platform name,
       
  1076                  * i.e. as a native font.
       
  1077                  */
       
  1078                 fontFileName = platformFontName;
       
  1079             } else {
       
  1080                 if (f < numCoreFonts) {
       
  1081                     /* If platform APIs also need to access the font, add it
       
  1082                      * to a set to be registered with the platform too.
       
  1083                      * This may be used to add the parent directory to the X11
       
  1084                      * font path if its not already there. See the docs for the
       
  1085                      * subclass implementation.
       
  1086                      * This is now mainly for the benefit of X11-based AWT
       
  1087                      * But for historical reasons, 2D initialisation code
       
  1088                      * makes these calls.
       
  1089                      * If the fontconfiguration file is properly set up
       
  1090                      * so that all fonts are mapped to files and all their
       
  1091                      * appropriate directories are specified, then this
       
  1092                      * method will be low cost as it will return after
       
  1093                      * a test that finds a null lookup map.
       
  1094                      */
       
  1095                     addFontToPlatformFontPath(platformFontName);
       
  1096                 }
       
  1097                 nativeNames = getNativeNames(fontFileName, platformFontName);
       
  1098             }
       
  1099             /* Uncomment these two lines to "generate" the XLFD->filename
       
  1100              * mappings needed to speed start-up on Solaris.
       
  1101              * Augment this with the appendedpathname and the mappings
       
  1102              * for native (F3) fonts
       
  1103              */
       
  1104             //String platName = platformFontName.replaceAll(" ", "_");
       
  1105             //System.out.println("filename."+platName+"="+fontFileName);
       
  1106             registerFontFile(fontFileName, nativeNames,
       
  1107                              Font2D.FONT_CONFIG_RANK, true);
       
  1108 
       
  1109 
       
  1110         }
       
  1111         /* This registers accumulated paths from the calls to
       
  1112          * addFontToPlatformFontPath(..) and any specified by
       
  1113          * the font configuration. Rather than registering
       
  1114          * the fonts it puts them in a place and form suitable for
       
  1115          * the Toolkit to pick up and use if a toolkit is initialised,
       
  1116          * and if it uses X11 fonts.
       
  1117          */
       
  1118         registerPlatformFontsUsedByFontConfiguration();
       
  1119 
       
  1120         CompositeFontDescriptor[] compositeFontInfo
       
  1121                 = fontConfig.get2DCompositeFontInfo();
       
  1122         for (int i = 0; i < compositeFontInfo.length; i++) {
       
  1123             CompositeFontDescriptor descriptor = compositeFontInfo[i];
       
  1124             String[] componentFileNames = descriptor.getComponentFileNames();
       
  1125             String[] componentFaceNames = descriptor.getComponentFaceNames();
       
  1126 
       
  1127             /* It would be better eventually to handle this in the
       
  1128              * FontConfiguration code which should also remove duplicate slots
       
  1129              */
       
  1130             if (missingFontFiles != null) {
       
  1131                 for (int ii=0; ii<componentFileNames.length; ii++) {
       
  1132                     if (missingFontFiles.contains(componentFileNames[ii])) {
       
  1133                         componentFileNames[ii] = getDefaultFontFile();
       
  1134                         componentFaceNames[ii] = getDefaultFontFaceName();
       
  1135                     }
       
  1136                 }
       
  1137             }
       
  1138 
       
  1139             /* FontConfiguration needs to convey how many fonts it has added
       
  1140              * as fallback component fonts which should not affect metrics.
       
  1141              * The core component count will be the number of metrics slots.
       
  1142              * This does not preclude other mechanisms for adding
       
  1143              * fall back component fonts to the composite.
       
  1144              */
       
  1145             if (altNameCache != null) {
       
  1146                 FontManager.registerCompositeFont(
       
  1147                     descriptor.getFaceName(),
       
  1148                     componentFileNames, componentFaceNames,
       
  1149                     descriptor.getCoreComponentCount(),
       
  1150                     descriptor.getExclusionRanges(),
       
  1151                     descriptor.getExclusionRangeLimits(),
       
  1152                     true,
       
  1153                     altNameCache);
       
  1154             } else {
       
  1155                 FontManager.registerCompositeFont(
       
  1156                     descriptor.getFaceName(),
       
  1157                     componentFileNames, componentFaceNames,
       
  1158                     descriptor.getCoreComponentCount(),
       
  1159                     descriptor.getExclusionRanges(),
       
  1160                     descriptor.getExclusionRangeLimits(),
       
  1161                     true);
       
  1162             }
       
  1163             if (debugFonts) {
       
  1164                 logger.info("registered " + descriptor.getFaceName());
       
  1165             }
       
  1166         }
       
  1167     }
       
  1168 
       
  1169     /**
       
  1170      * Notifies graphics environment that the logical font configuration
       
  1171      * uses the given platform font name. The graphics environment may
       
  1172      * use this for platform specific initialization.
       
  1173      */
       
  1174     protected void addFontToPlatformFontPath(String platformFontName) {
       
  1175     }
       
  1176 
       
  1177     protected void registerPlatformFontsUsedByFontConfiguration() {
       
  1178     }
       
  1179 
       
  1180     /**
       
  1181      * Determines whether the given font is a logical font.
       
  1182      */
       
  1183     public static boolean isLogicalFont(Font f) {
       
  1184         return FontConfiguration.isLogicalFontFamilyName(f.getFamily());
       
  1185     }
       
  1186 
       
  1187     /**
       
  1188      * Return the default font configuration.
       
  1189      */
       
  1190     public FontConfiguration getFontConfiguration() {
       
  1191         return fontConfig;
       
  1192     }
       
  1193 
       
  1194     /**
       
  1195      * Return the bounds of a GraphicsDevice, less its screen insets.
   226      * Return the bounds of a GraphicsDevice, less its screen insets.
  1196      * See also java.awt.GraphicsEnvironment.getUsableBounds();
   227      * See also java.awt.GraphicsEnvironment.getUsableBounds();
  1197      */
   228      */
  1198     public static Rectangle getUsableBounds(GraphicsDevice gd) {
   229     public static Rectangle getUsableBounds(GraphicsDevice gd) {
  1199         GraphicsConfiguration gc = gd.getDefaultConfiguration();
   230         GraphicsConfiguration gc = gd.getDefaultConfiguration();
  1204         usableBounds.y += insets.top;
   235         usableBounds.y += insets.top;
  1205         usableBounds.width -= (insets.left + insets.right);
   236         usableBounds.width -= (insets.left + insets.right);
  1206         usableBounds.height -= (insets.top + insets.bottom);
   237         usableBounds.height -= (insets.top + insets.bottom);
  1207 
   238 
  1208         return usableBounds;
   239         return usableBounds;
  1209     }
       
  1210 
       
  1211     /**
       
  1212      * This method is provided for internal and exclusive use by Swing.
       
  1213      * This method should no longer be called, instead directly call
       
  1214      * FontManager.fontSupportsDefaultEncoding(Font).
       
  1215      * This method will be removed once Swing is updated to no longer
       
  1216      * call it.
       
  1217      */
       
  1218     public static boolean fontSupportsDefaultEncoding(Font font) {
       
  1219         return FontManager.fontSupportsDefaultEncoding(font);
       
  1220     }
       
  1221 
       
  1222     public static void useAlternateFontforJALocales() {
       
  1223         FontManager.useAlternateFontforJALocales();
       
  1224     }
       
  1225 
       
  1226     /*
       
  1227      * This invocation is not in a privileged block because
       
  1228      * all privileged operations (reading files and properties)
       
  1229      * was conducted on the creation of the GE
       
  1230      */
       
  1231     public void
       
  1232         createCompositeFonts(ConcurrentHashMap<String, Font2D> altNameCache,
       
  1233                              boolean preferLocale,
       
  1234                              boolean preferProportional) {
       
  1235 
       
  1236         FontConfiguration fontConfig =
       
  1237             createFontConfiguration(preferLocale, preferProportional);
       
  1238         initCompositeFonts(fontConfig, altNameCache);
       
  1239     }
       
  1240 
       
  1241     /* If (as we do on X11) need to set a platform font path,
       
  1242      * then the needed path may be specified by the platform
       
  1243      * specific FontConfiguration class & data file. Such platforms
       
  1244      * (ie X11) need to override this method to retrieve this information
       
  1245      * into suitable data structures.
       
  1246      */
       
  1247     protected void getPlatformFontPathFromFontConfig() {
       
  1248     }
   240     }
  1249 
   241 
  1250     /**
   242     /**
  1251      * From the DisplayChangedListener interface; called
   243      * From the DisplayChangedListener interface; called
  1252      * when the display mode has been changed.
   244      * when the display mode has been changed.