SunGraphicsEnvironment.java revision 426
0N/A/*
0N/A * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation. Sun designates this
0N/A * particular file as subject to the "Classpath" exception as provided
0N/A * by Sun in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
0N/A * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0N/A * CA 95054 USA or visit www.sun.com if you need additional information or
0N/A * have any questions.
0N/A */
0N/A
0N/Apackage sun.java2d;
0N/A
0N/Aimport java.awt.Color;
0N/Aimport java.awt.Font;
0N/Aimport java.awt.Graphics2D;
0N/Aimport java.awt.GraphicsConfiguration;
0N/Aimport java.awt.GraphicsDevice;
0N/Aimport java.awt.GraphicsEnvironment;
0N/Aimport java.awt.Insets;
0N/Aimport java.awt.Rectangle;
0N/Aimport java.awt.Toolkit;
0N/Aimport java.awt.font.TextAttribute;
0N/Aimport java.awt.image.BufferedImage;
0N/Aimport java.io.BufferedReader;
0N/Aimport java.io.File;
0N/Aimport java.io.FileInputStream;
0N/Aimport java.io.FilenameFilter;
0N/Aimport java.io.InputStreamReader;
0N/Aimport java.io.IOException;
0N/Aimport java.text.AttributedCharacterIterator;
0N/Aimport java.util.ArrayList;
0N/Aimport java.util.HashSet;
0N/Aimport java.util.Iterator;
0N/Aimport java.util.Locale;
0N/Aimport java.util.Map;
0N/Aimport java.util.NoSuchElementException;
0N/Aimport java.util.Set;
0N/Aimport java.util.StringTokenizer;
0N/Aimport java.util.TreeMap;
0N/Aimport java.util.Vector;
0N/Aimport java.util.concurrent.ConcurrentHashMap;
0N/Aimport java.util.logging.Level;
0N/Aimport java.util.logging.Logger;
0N/Aimport sun.awt.AppContext;
0N/Aimport sun.awt.DisplayChangedListener;
0N/Aimport sun.awt.FontConfiguration;
0N/Aimport sun.awt.SunDisplayChanger;
0N/Aimport sun.font.CompositeFontDescriptor;
0N/Aimport sun.font.Font2D;
0N/Aimport sun.font.FontManager;
0N/Aimport sun.font.NativeFont;
0N/A
0N/A/**
0N/A * This is an implementation of a GraphicsEnvironment object for the
0N/A * default local GraphicsEnvironment.
0N/A *
0N/A * @see GraphicsDevice
0N/A * @see GraphicsConfiguration
0N/A */
0N/A
0N/Apublic abstract class SunGraphicsEnvironment extends GraphicsEnvironment
0N/A implements FontSupport, DisplayChangedListener {
0N/A
0N/A public static boolean isLinux;
0N/A public static boolean isSolaris;
426N/A public static boolean isOpenSolaris;
0N/A public static boolean isWindows;
0N/A public static boolean noType1Font;
0N/A private static Font defaultFont;
0N/A private static String defaultFontFileName;
0N/A private static String defaultFontName;
0N/A public static final String lucidaFontName = "Lucida Sans Regular";
0N/A public static final String lucidaFileName = "LucidaSansRegular.ttf";
0N/A public static boolean debugFonts = false;
0N/A protected static Logger logger = null;
0N/A private static ArrayList badFonts;
0N/A public static String jreLibDirName;
0N/A public static String jreFontDirName;
0N/A private static HashSet<String> missingFontFiles = null;
0N/A
0N/A private FontConfiguration fontConfig;
0N/A
0N/A /* fontPath is the location of all fonts on the system, excluding the
0N/A * JRE's own font directory but including any path specified using the
0N/A * sun.java2d.fontpath property. Together with that property, it is
0N/A * initialised by the getPlatformFontPath() method
0N/A * This call must be followed by a call to registerFontDirs(fontPath)
0N/A * once any extra debugging path has been appended.
0N/A */
0N/A protected String fontPath;
0N/A
0N/A /* discoveredAllFonts is set to true when all fonts on the font path are
0N/A * discovered. This usually also implies opening, validating and
0N/A * registering, but an implementation may be optimized to avold this.
0N/A * So see also "loadedAllFontFiles"
0N/A */
0N/A private boolean discoveredAllFonts = false;
0N/A
0N/A /* loadedAllFontFiles is set to true when all fonts on the font path are
0N/A * actually opened, validated and registered. This always implies
0N/A * discoveredAllFonts is true.
0N/A */
0N/A private boolean loadedAllFontFiles = false;
0N/A
0N/A protected HashSet registeredFontFiles = new HashSet();
0N/A public static String eudcFontFileName; /* Initialised only on windows */
0N/A
0N/A private static boolean isOpenJDK;
0N/A /**
0N/A * A few things in Java 2D code are different in OpenJDK,
0N/A * so need a way to tell which implementation this is.
0N/A * The absence of Lucida Sans Regular is the simplest way for now.
0N/A */
0N/A public static boolean isOpenJDK() {
0N/A return isOpenJDK;
0N/A }
0N/A
0N/A static {
0N/A java.security.AccessController.doPrivileged(
0N/A new java.security.PrivilegedAction() {
0N/A public Object run() {
0N/A
0N/A jreLibDirName = System.getProperty("java.home","") +
0N/A File.separator + "lib";
0N/A jreFontDirName = jreLibDirName + File.separator + "fonts";
0N/A File lucidaFile =
0N/A new File(jreFontDirName + File.separator + lucidaFileName);
0N/A isOpenJDK = !lucidaFile.exists();
0N/A
0N/A String debugLevel =
0N/A System.getProperty("sun.java2d.debugfonts");
0N/A
0N/A if (debugLevel != null && !debugLevel.equals("false")) {
0N/A debugFonts = true;
0N/A logger = Logger.getLogger("sun.java2d");
0N/A if (debugLevel.equals("warning")) {
0N/A logger.setLevel(Level.WARNING);
0N/A } else if (debugLevel.equals("severe")) {
0N/A logger.setLevel(Level.SEVERE);
0N/A }
0N/A }
0N/A return null;
0N/A }
0N/A });
0N/A };
0N/A
0N/A public SunGraphicsEnvironment() {
0N/A java.security.AccessController.doPrivileged(
0N/A new java.security.PrivilegedAction() {
0N/A public Object run() {
0N/A String osName = System.getProperty("os.name");
0N/A if ("Linux".equals(osName)) {
0N/A isLinux = true;
0N/A } else if ("SunOS".equals(osName)) {
0N/A isSolaris = true;
426N/A String version = System.getProperty("os.version", "0.0");
426N/A try {
426N/A float ver = Float.parseFloat(version);
426N/A if (ver > 5.10f) {
426N/A File f = new File("/etc/release");
426N/A FileInputStream fis = new FileInputStream(f);
426N/A InputStreamReader isr
426N/A = new InputStreamReader(fis, "ISO-8859-1");
426N/A BufferedReader br = new BufferedReader(isr);
426N/A String line = br.readLine();
426N/A if (line.indexOf("OpenSolaris") >= 0) {
426N/A isOpenSolaris = true;
426N/A }
426N/A fis.close();
426N/A }
426N/A } catch (Exception e) {
426N/A }
0N/A } else if ("Windows".equals(osName)) {
0N/A isWindows = true;
0N/A }
0N/A
0N/A noType1Font = "true".
0N/A equals(System.getProperty("sun.java2d.noType1Font"));
0N/A
426N/A if (!isOpenJDK()) {
0N/A defaultFontName = lucidaFontName;
0N/A if (useAbsoluteFontFileNames()) {
0N/A defaultFontFileName =
0N/A jreFontDirName + File.separator + lucidaFileName;
0N/A } else {
0N/A defaultFontFileName = lucidaFileName;
0N/A }
0N/A }
0N/A
0N/A File badFontFile =
0N/A new File(jreFontDirName + File.separator + "badfonts.txt");
0N/A if (badFontFile.exists()) {
0N/A FileInputStream fis = null;
0N/A try {
0N/A badFonts = new ArrayList();
0N/A fis = new FileInputStream(badFontFile);
0N/A InputStreamReader isr = new InputStreamReader(fis);
0N/A BufferedReader br = new BufferedReader(isr);
0N/A while (true) {
0N/A String name = br.readLine();
0N/A if (name == null) {
0N/A break;
0N/A } else {
0N/A if (debugFonts) {
0N/A logger.warning("read bad font: " + name);
0N/A }
0N/A badFonts.add(name);
0N/A }
0N/A }
0N/A } catch (IOException e) {
0N/A try {
0N/A if (fis != null) {
0N/A fis.close();
0N/A }
0N/A } catch (IOException ioe) {
0N/A }
0N/A }
0N/A }
0N/A
0N/A /* Here we get the fonts in jre/lib/fonts and register them
0N/A * so they are always available and preferred over other fonts.
0N/A * This needs to be registered before the composite fonts as
0N/A * otherwise some native font that corresponds may be found
0N/A * as we don't have a way to handle two fonts of the same
0N/A * name, so the JRE one must be the first one registered.
0N/A * Pass "true" to registerFonts method as on-screen these
0N/A * JRE fonts always go through the T2K rasteriser.
0N/A */
0N/A if (isLinux) {
0N/A /* Linux font configuration uses these fonts */
0N/A registerFontDir(jreFontDirName);
0N/A }
0N/A registerFontsInDir(jreFontDirName, true, Font2D.JRE_RANK,
0N/A true, false);
0N/A
0N/A /* Register the JRE fonts so that the native platform can
0N/A * access them. This is used only on Windows so that when
0N/A * printing the printer driver can access the fonts.
0N/A */
0N/A registerJREFontsWithPlatform(jreFontDirName);
0N/A
0N/A /* Create the font configuration and get any font path
0N/A * that might be specified.
0N/A */
0N/A fontConfig = createFontConfiguration();
426N/A if (isOpenJDK()) {
426N/A String[] fontInfo = FontManager.getDefaultPlatformFont();
426N/A defaultFontName = fontInfo[0];
426N/A defaultFontFileName = fontInfo[1];
426N/A }
0N/A getPlatformFontPathFromFontConfig();
0N/A
0N/A String extraFontPath = fontConfig.getExtraFontPath();
0N/A
0N/A /* In prior releases the debugging font path replaced
0N/A * all normally located font directories except for the
0N/A * JRE fonts dir. This directory is still always located and
0N/A * placed at the head of the path but as an augmentation
0N/A * to the previous behaviour the
0N/A * changes below allow you to additionally append to
0N/A * the font path by starting with append: or prepend by
0N/A * starting with a prepend: sign. Eg: to append
0N/A * -Dsun.java2d.fontpath=append:/usr/local/myfonts
0N/A * and to prepend
0N/A * -Dsun.java2d.fontpath=prepend:/usr/local/myfonts Disp
0N/A *
0N/A * If there is an appendedfontpath it in the font configuration
0N/A * it is used instead of searching the system for dirs.
0N/A * The behaviour of append and prepend is then similar
0N/A * to the normal case. ie it goes after what
0N/A * you prepend and * before what you append. If the
0N/A * sun.java2d.fontpath property is used, but it
0N/A * neither the append or prepend syntaxes is used then as
0N/A * except for the JRE dir the path is replaced and it is
0N/A * up to you to make sure that all the right directories
0N/A * are located. This is platform and locale-specific so
0N/A * its almost impossible to get right, so it should be
0N/A * used with caution.
0N/A */
0N/A boolean prependToPath = false;
0N/A boolean appendToPath = false;
0N/A String dbgFontPath = System.getProperty("sun.java2d.fontpath");
0N/A
0N/A if (dbgFontPath != null) {
0N/A if (dbgFontPath.startsWith("prepend:")) {
0N/A prependToPath = true;
0N/A dbgFontPath =
0N/A dbgFontPath.substring("prepend:".length());
0N/A } else if (dbgFontPath.startsWith("append:")) {
0N/A appendToPath = true;
0N/A dbgFontPath =
0N/A dbgFontPath.substring("append:".length());
0N/A }
0N/A }
0N/A
0N/A if (debugFonts) {
0N/A logger.info("JRE font directory: " + jreFontDirName);
0N/A logger.info("Extra font path: " + extraFontPath);
0N/A logger.info("Debug font path: " + dbgFontPath);
0N/A }
0N/A
0N/A if (dbgFontPath != null) {
0N/A /* In debugging mode we register all the paths
0N/A * Caution: this is a very expensive call on Solaris:-
0N/A */
0N/A fontPath = getPlatformFontPath(noType1Font);
0N/A
0N/A if (extraFontPath != null) {
0N/A fontPath =
0N/A extraFontPath + File.pathSeparator + fontPath;
0N/A }
0N/A if (appendToPath) {
0N/A fontPath = fontPath + File.pathSeparator + dbgFontPath;
0N/A } else if (prependToPath) {
0N/A fontPath = dbgFontPath + File.pathSeparator + fontPath;
0N/A } else {
0N/A fontPath = dbgFontPath;
0N/A }
0N/A registerFontDirs(fontPath);
0N/A } else if (extraFontPath != null) {
0N/A /* If the font configuration contains an "appendedfontpath"
0N/A * entry, it is interpreted as a set of locations that
0N/A * should always be registered.
0N/A * It may be additional to locations normally found for
0N/A * that place, or it may be locations that need to have
0N/A * all their paths registered to locate all the needed
0N/A * platform names.
0N/A * This is typically when the same .TTF file is referenced
0N/A * from multiple font.dir files and all of these must be
0N/A * read to find all the native (XLFD) names for the font,
0N/A * so that X11 font APIs can be used for as many code
0N/A * points as possible.
0N/A */
0N/A registerFontDirs(extraFontPath);
0N/A }
0N/A
0N/A /* On Solaris, we need to register the Japanese TrueType
0N/A * directory so that we can find the corresponding bitmap
0N/A * fonts. This could be done by listing the directory in
0N/A * the font configuration file, but we don't want to
0N/A * confuse users with this quirk. There are no bitmap fonts
0N/A * for other writing systems that correspond to TrueType
0N/A * fonts and have matching XLFDs. We need to register the
0N/A * bitmap fonts only in environments where they're on the
0N/A * X font path, i.e., in the Japanese locale.
0N/A * Note that if the X Toolkit is in use the font path isn't
0N/A * set up by JDK, but users of a JA locale should have it
0N/A * set up already by their login environment.
0N/A */
0N/A if (isSolaris && Locale.JAPAN.equals(Locale.getDefault())) {
0N/A registerFontDir("/usr/openwin/lib/locale/ja/X11/fonts/TT");
0N/A }
0N/A
0N/A initCompositeFonts(fontConfig, null);
0N/A
0N/A /* Establish the default font to be used by SG2D etc */
0N/A defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
0N/A
0N/A return null;
0N/A }
0N/A });
0N/A }
0N/A
0N/A protected GraphicsDevice[] screens;
0N/A
0N/A /**
0N/A * Returns an array of all of the screen devices.
0N/A */
0N/A public synchronized GraphicsDevice[] getScreenDevices() {
0N/A GraphicsDevice[] ret = screens;
0N/A if (ret == null) {
0N/A int num = getNumScreens();
0N/A ret = new GraphicsDevice[num];
0N/A for (int i = 0; i < num; i++) {
0N/A ret[i] = makeScreenDevice(i);
0N/A }
0N/A screens = ret;
0N/A }
0N/A return ret;
0N/A }
0N/A
0N/A protected abstract int getNumScreens();
0N/A protected abstract GraphicsDevice makeScreenDevice(int screennum);
0N/A
0N/A /**
0N/A * Returns the default screen graphics device.
0N/A */
0N/A public GraphicsDevice getDefaultScreenDevice() {
0N/A return getScreenDevices()[0];
0N/A }
0N/A
0N/A /**
0N/A * Returns a Graphics2D object for rendering into the
0N/A * given BufferedImage.
0N/A * @throws NullPointerException if BufferedImage argument is null
0N/A */
0N/A public Graphics2D createGraphics(BufferedImage img) {
0N/A if (img == null) {
0N/A throw new NullPointerException("BufferedImage cannot be null");
0N/A }
0N/A SurfaceData sd = SurfaceData.getPrimarySurfaceData(img);
0N/A return new SunGraphics2D(sd, Color.white, Color.black, defaultFont);
0N/A }
0N/A
0N/A /* A call to this method should be followed by a call to
0N/A * registerFontDirs(..)
0N/A */
0N/A protected String getPlatformFontPath(boolean noType1Font) {
0N/A if (fontPath == null) {
0N/A fontPath = FontManager.getFontPath(noType1Font);
0N/A }
0N/A return fontPath;
0N/A }
0N/A
0N/A private String[] platformFontDirs;
0N/A /**
0N/A * Get all directories which contain installed fonts.
0N/A */
0N/A public String[] getPlatformFontDirs() {
0N/A if (platformFontDirs == null) {
0N/A String path = getPlatformFontPath(noType1Font);
0N/A StringTokenizer parser =
0N/A new StringTokenizer(path, File.pathSeparator);;
0N/A ArrayList<String> pathList = new ArrayList<String>();
0N/A try {
0N/A while (parser.hasMoreTokens()) {
0N/A pathList.add(parser.nextToken());
0N/A }
0N/A } catch (NoSuchElementException e) {
0N/A }
0N/A platformFontDirs = pathList.toArray(new String[0]);
0N/A }
0N/A return platformFontDirs;
0N/A }
0N/A
0N/A /**
0N/A * Whether registerFontFile expects absolute or relative
0N/A * font file names.
0N/A */
0N/A protected boolean useAbsoluteFontFileNames() {
0N/A return true;
0N/A }
0N/A
0N/A /**
0N/A * Returns file name for default font, either absolute
0N/A * or relative as needed by registerFontFile.
0N/A */
0N/A public String getDefaultFontFile() {
0N/A return defaultFontFileName;
0N/A }
0N/A
0N/A /**
0N/A * Returns face name for default font, or null if
0N/A * no face names are used for CompositeFontDescriptors
0N/A * for this platform.
0N/A */
0N/A public String getDefaultFontFaceName() {
0N/A return defaultFontName;
0N/A }
0N/A
0N/A public void loadFonts() {
0N/A if (discoveredAllFonts) {
0N/A return;
0N/A }
0N/A /* Use lock specific to the font system */
0N/A synchronized (lucidaFontName) {
0N/A if (debugFonts) {
0N/A Thread.dumpStack();
0N/A logger.info("SunGraphicsEnvironment.loadFonts() called");
0N/A }
0N/A FontManager.initialiseDeferredFonts();
0N/A
0N/A java.security.AccessController.doPrivileged(
0N/A new java.security.PrivilegedAction() {
0N/A public Object run() {
0N/A if (fontPath == null) {
0N/A fontPath = getPlatformFontPath(noType1Font);
0N/A registerFontDirs(fontPath);
0N/A }
0N/A if (fontPath != null) {
0N/A // this will find all fonts including those already
0N/A // registered. But we have checks in place to prevent
0N/A // double registration.
0N/A if (!FontManager.gotFontsFromPlatform()) {
0N/A registerFontsOnPath(fontPath, false,
0N/A Font2D.UNKNOWN_RANK,
0N/A false, true);
0N/A loadedAllFontFiles = true;
0N/A }
0N/A }
0N/A FontManager.registerOtherFontFiles(registeredFontFiles);
0N/A discoveredAllFonts = true;
0N/A return null;
0N/A }
0N/A });
0N/A }
0N/A }
0N/A
0N/A
0N/A public void loadFontFiles() {
0N/A loadFonts();
0N/A if (loadedAllFontFiles) {
0N/A return;
0N/A }
0N/A /* Use lock specific to the font system */
0N/A synchronized (lucidaFontName) {
0N/A if (debugFonts) {
0N/A Thread.dumpStack();
0N/A logger.info("loadAllFontFiles() called");
0N/A }
0N/A java.security.AccessController.doPrivileged(
0N/A new java.security.PrivilegedAction() {
0N/A public Object run() {
0N/A if (fontPath == null) {
0N/A fontPath = getPlatformFontPath(noType1Font);
0N/A }
0N/A if (fontPath != null) {
0N/A // this will find all fonts including those already
0N/A // registered. But we have checks in place to prevent
0N/A // double registration.
0N/A registerFontsOnPath(fontPath, false,
0N/A Font2D.UNKNOWN_RANK,
0N/A false, true);
0N/A }
0N/A loadedAllFontFiles = true;
0N/A return null;
0N/A }
0N/A });
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * This is for use only within getAllFonts().
0N/A * Fonts listed in the fontconfig files for windows were all
0N/A * on the "deferred" initialisation list. They were registered
0N/A * either in the course of the application, or in the call to
0N/A * loadFonts() within getAllFonts(). The fontconfig file specifies
0N/A * the names of the fonts using the English names. If there's a
0N/A * different name in the execution locale, then the platform will
0N/A * report that, and we will construct the font with both names, and
0N/A * thereby enumerate it twice. This happens for Japanese fonts listed
0N/A * in the windows fontconfig, when run in the JA locale. The solution
0N/A * is to rely (in this case) on the platform's font->file mapping to
0N/A * determine that this name corresponds to a file we already registered.
0N/A * This works because
0N/A * - we know when we get here all deferred fonts are already initialised
0N/A * - when we register a font file, we register all fonts in it.
0N/A * - we know the fontconfig fonts are all in the windows registry
0N/A */
0N/A private boolean isNameForRegisteredFile(String fontName) {
0N/A String fileName = FontManager.getFileNameForFontName(fontName);
0N/A if (fileName == null) {
0N/A return false;
0N/A }
0N/A return registeredFontFiles.contains(fileName);
0N/A }
0N/A
0N/A private Font[] allFonts;
0N/A
0N/A /**
0N/A * Returns all fonts installed in this environment.
0N/A */
0N/A public Font[] getAllInstalledFonts() {
0N/A if (allFonts == null) {
0N/A loadFonts();
0N/A TreeMap fontMapNames = new TreeMap();
0N/A /* warning: the number of composite fonts could change dynamically
0N/A * if applications are allowed to create them. "allfonts" could
0N/A * then be stale.
0N/A */
0N/A
0N/A Font2D[] allfonts = FontManager.getRegisteredFonts();
0N/A for (int i=0; i < allfonts.length; i++) {
0N/A if (!(allfonts[i] instanceof NativeFont)) {
0N/A fontMapNames.put(allfonts[i].getFontName(null),
0N/A allfonts[i]);
0N/A }
0N/A }
0N/A
0N/A String[] platformNames = FontManager.getFontNamesFromPlatform();
0N/A if (platformNames != null) {
0N/A for (int i=0; i<platformNames.length; i++) {
0N/A if (!isNameForRegisteredFile(platformNames[i])) {
0N/A fontMapNames.put(platformNames[i], null);
0N/A }
0N/A }
0N/A }
0N/A
0N/A String[] fontNames = null;
0N/A if (fontMapNames.size() > 0) {
0N/A fontNames = new String[fontMapNames.size()];
0N/A Object [] keyNames = fontMapNames.keySet().toArray();
0N/A for (int i=0; i < keyNames.length; i++) {
0N/A fontNames[i] = (String)keyNames[i];
0N/A }
0N/A }
0N/A Font[] fonts = new Font[fontNames.length];
0N/A for (int i=0; i < fontNames.length; i++) {
0N/A fonts[i] = new Font(fontNames[i], Font.PLAIN, 1);
0N/A Font2D f2d = (Font2D)fontMapNames.get(fontNames[i]);
0N/A if (f2d != null) {
0N/A FontManager.setFont2D(fonts[i], f2d.handle);
0N/A }
0N/A }
0N/A allFonts = fonts;
0N/A }
0N/A
0N/A Font []copyFonts = new Font[allFonts.length];
0N/A System.arraycopy(allFonts, 0, copyFonts, 0, allFonts.length);
0N/A return copyFonts;
0N/A }
0N/A
0N/A /**
0N/A * Returns all fonts available in this environment.
0N/A */
0N/A public Font[] getAllFonts() {
0N/A Font[] installedFonts = getAllInstalledFonts();
0N/A Font[] created = FontManager.getCreatedFonts();
0N/A if (created == null || created.length == 0) {
0N/A return installedFonts;
0N/A } else {
0N/A int newlen = installedFonts.length + created.length;
0N/A Font [] fonts = java.util.Arrays.copyOf(installedFonts, newlen);
0N/A System.arraycopy(created, 0, fonts,
0N/A installedFonts.length, created.length);
0N/A return fonts;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Default locale can be changed but we need to know the initial locale
0N/A * as that is what is used by native code. Changing Java default locale
0N/A * doesn't affect that.
0N/A * Returns the locale in use when using native code to communicate
0N/A * with platform APIs. On windows this is known as the "system" locale,
0N/A * and it is usually the same as the platform locale, but not always,
0N/A * so this method also checks an implementation property used only
0N/A * on windows and uses that if set.
0N/A */
0N/A private static Locale systemLocale = null;
0N/A public static Locale getSystemStartupLocale() {
0N/A if (systemLocale == null) {
0N/A systemLocale = (Locale)
0N/A java.security.AccessController.doPrivileged(
0N/A new java.security.PrivilegedAction() {
0N/A public Object run() {
0N/A /* On windows the system locale may be different than the
0N/A * user locale. This is an unsupported configuration, but
0N/A * in that case we want to return a dummy locale that will
0N/A * never cause a match in the usage of this API. This is
0N/A * important because Windows documents that the family
0N/A * names of fonts are enumerated using the language of
0N/A * the system locale. BY returning a dummy locale in that
0N/A * case we do not use the platform API which would not
0N/A * return us the names we want.
0N/A */
0N/A String fileEncoding = System.getProperty("file.encoding", "");
0N/A String sysEncoding = System.getProperty("sun.jnu.encoding");
0N/A if (sysEncoding != null && !sysEncoding.equals(fileEncoding)) {
0N/A return Locale.ROOT;
0N/A }
0N/A
0N/A String language = System.getProperty("user.language", "en");
0N/A String country = System.getProperty("user.country","");
0N/A String variant = System.getProperty("user.variant","");
0N/A return new Locale(language, country, variant);
0N/A }
0N/A });
0N/A }
0N/A return systemLocale;
0N/A }
0N/A
0N/A /* Really we need only the JRE fonts family names, but there's little
0N/A * overhead in doing this the easy way by adding all the currently
0N/A * known fonts.
0N/A */
0N/A protected void getJREFontFamilyNames(TreeMap<String,String> familyNames,
0N/A Locale requestedLocale) {
0N/A FontManager.registerDeferredJREFonts(jreFontDirName);
0N/A Font2D[] physicalfonts = FontManager.getPhysicalFonts();
0N/A for (int i=0; i < physicalfonts.length; i++) {
0N/A if (!(physicalfonts[i] instanceof NativeFont)) {
0N/A String name =
0N/A physicalfonts[i].getFamilyName(requestedLocale);
0N/A familyNames.put(name.toLowerCase(requestedLocale), name);
0N/A }
0N/A }
0N/A }
0N/A
0N/A private String[] allFamilies; // cache for default locale only
0N/A private Locale lastDefaultLocale;
0N/A
0N/A public String[] getInstalledFontFamilyNames(Locale requestedLocale) {
0N/A if (requestedLocale == null) {
0N/A requestedLocale = Locale.getDefault();
0N/A }
0N/A if (allFamilies != null && lastDefaultLocale != null &&
0N/A requestedLocale.equals(lastDefaultLocale)) {
0N/A String[] copyFamilies = new String[allFamilies.length];
0N/A System.arraycopy(allFamilies, 0, copyFamilies,
0N/A 0, allFamilies.length);
0N/A return copyFamilies;
0N/A }
0N/A
0N/A TreeMap<String,String> familyNames = new TreeMap<String,String>();
0N/A // these names are always there and aren't localised
0N/A String str;
0N/A str = Font.SERIF; familyNames.put(str.toLowerCase(), str);
0N/A str = Font.SANS_SERIF; familyNames.put(str.toLowerCase(), str);
0N/A str = Font.MONOSPACED; familyNames.put(str.toLowerCase(), str);
0N/A str = Font.DIALOG; familyNames.put(str.toLowerCase(), str);
0N/A str = Font.DIALOG_INPUT; familyNames.put(str.toLowerCase(), str);
0N/A
0N/A /* Platform APIs may be used to get the set of available family
0N/A * names for the current default locale so long as it is the same
0N/A * as the start-up system locale, rather than loading all fonts.
0N/A */
0N/A if (requestedLocale.equals(getSystemStartupLocale()) &&
0N/A FontManager.getFamilyNamesFromPlatform(familyNames,
0N/A requestedLocale)) {
0N/A /* Augment platform names with JRE font family names */
0N/A getJREFontFamilyNames(familyNames, requestedLocale);
0N/A } else {
0N/A loadFontFiles();
0N/A Font2D[] physicalfonts = FontManager.getPhysicalFonts();
0N/A for (int i=0; i < physicalfonts.length; i++) {
0N/A if (!(physicalfonts[i] instanceof NativeFont)) {
0N/A String name =
0N/A physicalfonts[i].getFamilyName(requestedLocale);
0N/A familyNames.put(name.toLowerCase(requestedLocale), name);
0N/A }
0N/A }
0N/A }
0N/A
0N/A String[] retval = new String[familyNames.size()];
0N/A Object [] keyNames = familyNames.keySet().toArray();
0N/A for (int i=0; i < keyNames.length; i++) {
0N/A retval[i] = (String)familyNames.get(keyNames[i]);
0N/A }
0N/A if (requestedLocale.equals(Locale.getDefault())) {
0N/A lastDefaultLocale = requestedLocale;
0N/A allFamilies = new String[retval.length];
0N/A System.arraycopy(retval, 0, allFamilies, 0, allFamilies.length);
0N/A }
0N/A return retval;
0N/A }
0N/A
0N/A public String[] getAvailableFontFamilyNames(Locale requestedLocale) {
0N/A String[] installed = getInstalledFontFamilyNames(requestedLocale);
0N/A /* Use a new TreeMap as used in getInstalledFontFamilyNames
0N/A * and insert all the keys in lower case, so that the sort order
0N/A * is the same as the installed families. This preserves historical
0N/A * behaviour and inserts new families in the right place.
0N/A * It would have been marginally more efficient to directly obtain
0N/A * the tree map and just insert new entries, but not so much as
0N/A * to justify the extra internal interface.
0N/A */
0N/A TreeMap<String, String> map = FontManager.getCreatedFontFamilyNames();
0N/A if (map == null || map.size() == 0) {
0N/A return installed;
0N/A } else {
0N/A for (int i=0; i<installed.length; i++) {
0N/A map.put(installed[i].toLowerCase(requestedLocale),
0N/A installed[i]);
0N/A }
0N/A String[] retval = new String[map.size()];
0N/A Object [] keyNames = map.keySet().toArray();
0N/A for (int i=0; i < keyNames.length; i++) {
0N/A retval[i] = (String)map.get(keyNames[i]);
0N/A }
0N/A return retval;
0N/A }
0N/A }
0N/A
0N/A public String[] getAvailableFontFamilyNames() {
0N/A return getAvailableFontFamilyNames(Locale.getDefault());
0N/A }
0N/A
0N/A /**
0N/A * Returns a file name for the physical font represented by this platform
0N/A * font name. The default implementation tries to obtain the file name
0N/A * from the font configuration.
0N/A * Subclasses may override to provide information from other sources.
0N/A */
0N/A protected String getFileNameFromPlatformName(String platformFontName) {
0N/A return fontConfig.getFileNameFromPlatformName(platformFontName);
0N/A }
0N/A
0N/A public static class TTFilter implements FilenameFilter {
0N/A public boolean accept(File dir,String name) {
0N/A /* all conveniently have the same suffix length */
0N/A int offset = name.length()-4;
0N/A if (offset <= 0) { /* must be at least A.ttf */
0N/A return false;
0N/A } else {
0N/A return(name.startsWith(".ttf", offset) ||
0N/A name.startsWith(".TTF", offset) ||
0N/A name.startsWith(".ttc", offset) ||
0N/A name.startsWith(".TTC", offset));
0N/A }
0N/A }
0N/A }
0N/A
0N/A public static class T1Filter implements FilenameFilter {
0N/A public boolean accept(File dir,String name) {
0N/A if (noType1Font) {
0N/A return false;
0N/A }
0N/A /* all conveniently have the same suffix length */
0N/A int offset = name.length()-4;
0N/A if (offset <= 0) { /* must be at least A.pfa */
0N/A return false;
0N/A } else {
0N/A return(name.startsWith(".pfa", offset) ||
0N/A name.startsWith(".pfb", offset) ||
0N/A name.startsWith(".PFA", offset) ||
0N/A name.startsWith(".PFB", offset));
0N/A }
0N/A }
0N/A }
0N/A
0N/A public static class TTorT1Filter implements FilenameFilter {
0N/A public boolean accept(File dir, String name) {
0N/A
0N/A /* all conveniently have the same suffix length */
0N/A int offset = name.length()-4;
0N/A if (offset <= 0) { /* must be at least A.ttf or A.pfa */
0N/A return false;
0N/A } else {
0N/A boolean isTT =
0N/A name.startsWith(".ttf", offset) ||
0N/A name.startsWith(".TTF", offset) ||
0N/A name.startsWith(".ttc", offset) ||
0N/A name.startsWith(".TTC", offset);
0N/A if (isTT) {
0N/A return true;
0N/A } else if (noType1Font) {
0N/A return false;
0N/A } else {
0N/A return(name.startsWith(".pfa", offset) ||
0N/A name.startsWith(".pfb", offset) ||
0N/A name.startsWith(".PFA", offset) ||
0N/A name.startsWith(".PFB", offset));
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A /* No need to keep consing up new instances - reuse a singleton.
0N/A * The trade-off is that these objects don't get GC'd.
0N/A */
0N/A public static final TTFilter ttFilter = new TTFilter();
0N/A public static final T1Filter t1Filter = new T1Filter();
0N/A
0N/A /* The majority of the register functions in this class are
0N/A * registering platform fonts in the JRE's font maps.
0N/A * The next one is opposite in function as it registers the JRE
0N/A * fonts as platform fonts. If subsequent to calling this
0N/A * your implementation enumerates platform fonts in a way that
0N/A * would return these fonts too you may get duplicates.
0N/A * This function is primarily used to install the JRE fonts
0N/A * so that the native platform can access them.
0N/A * It is intended to be overridden by platform subclasses
0N/A * Currently minimal use is made of this as generally
0N/A * Java 2D doesn't need the platform to be able to
0N/A * use its fonts and platforms which already have matching
0N/A * fonts registered (possibly even from other different JRE
0N/A * versions) generally can't be guaranteed to use the
0N/A * one registered by this JRE version in response to
0N/A * requests from this JRE.
0N/A */
0N/A protected void registerJREFontsWithPlatform(String pathName) {
0N/A return;
0N/A }
0N/A
0N/A /* Called from FontManager - has Solaris specific implementation */
0N/A public void register1dot0Fonts() {
0N/A java.security.AccessController.doPrivileged(
0N/A new java.security.PrivilegedAction() {
0N/A public Object run() {
0N/A String type1Dir = "/usr/openwin/lib/X11/fonts/Type1";
0N/A registerFontsInDir(type1Dir, true, Font2D.TYPE1_RANK,
0N/A false, false);
0N/A return null;
0N/A }
0N/A });
0N/A }
0N/A
0N/A protected void registerFontDirs(String pathName) {
0N/A return;
0N/A }
0N/A
0N/A /* Called to register fall back fonts */
0N/A public void registerFontsInDir(String dirName) {
0N/A registerFontsInDir(dirName, true, Font2D.JRE_RANK, true, false);
0N/A }
0N/A
0N/A private void registerFontsInDir(String dirName, boolean useJavaRasterizer,
0N/A int fontRank,
0N/A boolean defer, boolean resolveSymLinks) {
0N/A File pathFile = new File(dirName);
0N/A addDirFonts(dirName, pathFile, ttFilter,
0N/A FontManager.FONTFORMAT_TRUETYPE, useJavaRasterizer,
0N/A fontRank==Font2D.UNKNOWN_RANK ?
0N/A Font2D.TTF_RANK : fontRank,
0N/A defer, resolveSymLinks);
0N/A addDirFonts(dirName, pathFile, t1Filter,
0N/A FontManager.FONTFORMAT_TYPE1, useJavaRasterizer,
0N/A fontRank==Font2D.UNKNOWN_RANK ?
0N/A Font2D.TYPE1_RANK : fontRank,
0N/A defer, resolveSymLinks);
0N/A }
0N/A
0N/A private void registerFontsOnPath(String pathName,
0N/A boolean useJavaRasterizer, int fontRank,
0N/A boolean defer, boolean resolveSymLinks) {
0N/A
0N/A StringTokenizer parser = new StringTokenizer(pathName,
0N/A File.pathSeparator);
0N/A try {
0N/A while (parser.hasMoreTokens()) {
0N/A registerFontsInDir(parser.nextToken(),
0N/A useJavaRasterizer, fontRank,
0N/A defer, resolveSymLinks);
0N/A }
0N/A } catch (NoSuchElementException e) {
0N/A }
0N/A }
0N/A
0N/A protected void registerFontFile(String fontFileName, String[] nativeNames,
0N/A int fontRank, boolean defer) {
0N/A // REMIND: case compare depends on platform
0N/A if (registeredFontFiles.contains(fontFileName)) {
0N/A return;
0N/A }
0N/A int fontFormat;
0N/A if (ttFilter.accept(null, fontFileName)) {
0N/A fontFormat = FontManager.FONTFORMAT_TRUETYPE;
0N/A } else if (t1Filter.accept(null, fontFileName)) {
0N/A fontFormat = FontManager.FONTFORMAT_TYPE1;
0N/A } else {
0N/A fontFormat = FontManager.FONTFORMAT_NATIVE;
0N/A }
0N/A registeredFontFiles.add(fontFileName);
0N/A if (defer) {
0N/A FontManager.registerDeferredFont(fontFileName,
0N/A fontFileName, nativeNames,
0N/A fontFormat, false, fontRank);
0N/A } else {
0N/A FontManager.registerFontFile(fontFileName, nativeNames,
0N/A fontFormat, false, fontRank);
0N/A }
0N/A }
0N/A
0N/A protected void registerFontDir(String path) {
0N/A }
0N/A
0N/A protected String[] getNativeNames(String fontFileName,
0N/A String platformName) {
0N/A return null;
0N/A }
0N/A
0N/A /*
0N/A * helper function for registerFonts
0N/A */
0N/A private void addDirFonts(String dirName, File dirFile,
0N/A FilenameFilter filter,
0N/A int fontFormat, boolean useJavaRasterizer,
0N/A int fontRank,
0N/A boolean defer, boolean resolveSymLinks) {
0N/A String[] ls = dirFile.list(filter);
0N/A if (ls == null || ls.length == 0) {
0N/A return;
0N/A }
0N/A String[] fontNames = new String[ls.length];
0N/A String[][] nativeNames = new String[ls.length][];
0N/A int fontCount = 0;
0N/A
0N/A for (int i=0; i < ls.length; i++ ) {
0N/A File theFile = new File(dirFile, ls[i]);
0N/A String fullName = null;
0N/A if (resolveSymLinks) {
0N/A try {
0N/A fullName = theFile.getCanonicalPath();
0N/A } catch (IOException e) {
0N/A }
0N/A }
0N/A if (fullName == null) {
0N/A fullName = dirName + File.separator + ls[i];
0N/A }
0N/A
0N/A // REMIND: case compare depends on platform
0N/A if (registeredFontFiles.contains(fullName)) {
0N/A continue;
0N/A }
0N/A
0N/A if (badFonts != null && badFonts.contains(fullName)) {
0N/A if (debugFonts) {
0N/A logger.warning("skip bad font " + fullName);
0N/A }
0N/A continue; // skip this font file.
0N/A }
0N/A
0N/A registeredFontFiles.add(fullName);
0N/A
0N/A if (debugFonts && logger.isLoggable(Level.INFO)) {
0N/A String message = "Registering font " + fullName;
0N/A String[] natNames = getNativeNames(fullName, null);
0N/A if (natNames == null) {
0N/A message += " with no native name";
0N/A } else {
0N/A message += " with native name(s) " + natNames[0];
0N/A for (int nn = 1; nn < natNames.length; nn++) {
0N/A message += ", " + natNames[nn];
0N/A }
0N/A }
0N/A logger.info(message);
0N/A }
0N/A fontNames[fontCount] = fullName;
0N/A nativeNames[fontCount++] = getNativeNames(fullName, null);
0N/A }
0N/A FontManager.registerFonts(fontNames, nativeNames, fontCount,
0N/A fontFormat, useJavaRasterizer, fontRank,
0N/A defer);
0N/A return;
0N/A }
0N/A
0N/A /*
0N/A * A GE may verify whether a font file used in a fontconfiguration
0N/A * exists. If it doesn't then either we may substitute the default
0N/A * font, or perhaps elide it altogether from the composite font.
0N/A * This makes some sense on windows where the font file is only
0N/A * likely to be in one place. But on other OSes, eg Linux, the file
0N/A * can move around depending. So there we probably don't want to assume
0N/A * its missing and so won't add it to this list.
0N/A * If this list - missingFontFiles - is non-null then the composite
0N/A * font initialisation logic tests to see if a font file is in that
0N/A * set.
0N/A * Only one thread should be able to add to this set so we don't
0N/A * synchronize.
0N/A */
0N/A protected void addToMissingFontFileList(String fileName) {
0N/A if (missingFontFiles == null) {
0N/A missingFontFiles = new HashSet<String>();
0N/A }
0N/A missingFontFiles.add(fileName);
0N/A }
0N/A
0N/A /**
0N/A * Creates this environment's FontConfiguration.
0N/A */
0N/A protected abstract FontConfiguration createFontConfiguration();
0N/A
0N/A public abstract FontConfiguration
0N/A createFontConfiguration(boolean preferLocaleFonts,
0N/A boolean preferPropFonts);
0N/A
0N/A /*
0N/A * This method asks the font configuration API for all platform names
0N/A * used as components of composite/logical fonts and iterates over these
0N/A * looking up their corresponding file name and registers these fonts.
0N/A * It also ensures that the fonts are accessible via platform APIs.
0N/A * The composites themselves are then registered.
0N/A */
0N/A private void
0N/A initCompositeFonts(FontConfiguration fontConfig,
0N/A ConcurrentHashMap<String, Font2D> altNameCache) {
0N/A
0N/A int numCoreFonts = fontConfig.getNumberCoreFonts();
0N/A String[] fcFonts = fontConfig.getPlatformFontNames();
0N/A for (int f=0; f<fcFonts.length; f++) {
0N/A String platformFontName = fcFonts[f];
0N/A String fontFileName =
0N/A getFileNameFromPlatformName(platformFontName);
0N/A String[] nativeNames = null;
426N/A if (fontFileName == null || fontFileName.equals(platformFontName)){
0N/A /* No file located, so register using the platform name,
0N/A * i.e. as a native font.
0N/A */
0N/A fontFileName = platformFontName;
0N/A } else {
0N/A if (f < numCoreFonts) {
0N/A /* If platform APIs also need to access the font, add it
0N/A * to a set to be registered with the platform too.
0N/A * This may be used to add the parent directory to the X11
0N/A * font path if its not already there. See the docs for the
0N/A * subclass implementation.
0N/A * This is now mainly for the benefit of X11-based AWT
0N/A * But for historical reasons, 2D initialisation code
0N/A * makes these calls.
0N/A * If the fontconfiguration file is properly set up
0N/A * so that all fonts are mapped to files and all their
0N/A * appropriate directories are specified, then this
0N/A * method will be low cost as it will return after
0N/A * a test that finds a null lookup map.
0N/A */
0N/A addFontToPlatformFontPath(platformFontName);
0N/A }
0N/A nativeNames = getNativeNames(fontFileName, platformFontName);
0N/A }
0N/A /* Uncomment these two lines to "generate" the XLFD->filename
0N/A * mappings needed to speed start-up on Solaris.
0N/A * Augment this with the appendedpathname and the mappings
0N/A * for native (F3) fonts
0N/A */
0N/A //String platName = platformFontName.replaceAll(" ", "_");
0N/A //System.out.println("filename."+platName+"="+fontFileName);
0N/A registerFontFile(fontFileName, nativeNames,
0N/A Font2D.FONT_CONFIG_RANK, true);
0N/A
0N/A
0N/A }
0N/A /* This registers accumulated paths from the calls to
0N/A * addFontToPlatformFontPath(..) and any specified by
0N/A * the font configuration. Rather than registering
0N/A * the fonts it puts them in a place and form suitable for
0N/A * the Toolkit to pick up and use if a toolkit is initialised,
0N/A * and if it uses X11 fonts.
0N/A */
0N/A registerPlatformFontsUsedByFontConfiguration();
0N/A
0N/A CompositeFontDescriptor[] compositeFontInfo
0N/A = fontConfig.get2DCompositeFontInfo();
0N/A for (int i = 0; i < compositeFontInfo.length; i++) {
0N/A CompositeFontDescriptor descriptor = compositeFontInfo[i];
0N/A String[] componentFileNames = descriptor.getComponentFileNames();
0N/A String[] componentFaceNames = descriptor.getComponentFaceNames();
0N/A
0N/A /* It would be better eventually to handle this in the
0N/A * FontConfiguration code which should also remove duplicate slots
0N/A */
0N/A if (missingFontFiles != null) {
0N/A for (int ii=0; ii<componentFileNames.length; ii++) {
0N/A if (missingFontFiles.contains(componentFileNames[ii])) {
0N/A componentFileNames[ii] = getDefaultFontFile();
0N/A componentFaceNames[ii] = getDefaultFontFaceName();
0N/A }
0N/A }
0N/A }
0N/A
0N/A /* FontConfiguration needs to convey how many fonts it has added
0N/A * as fallback component fonts which should not affect metrics.
0N/A * The core component count will be the number of metrics slots.
0N/A * This does not preclude other mechanisms for adding
0N/A * fall back component fonts to the composite.
0N/A */
0N/A if (altNameCache != null) {
0N/A FontManager.registerCompositeFont(
0N/A descriptor.getFaceName(),
0N/A componentFileNames, componentFaceNames,
0N/A descriptor.getCoreComponentCount(),
0N/A descriptor.getExclusionRanges(),
0N/A descriptor.getExclusionRangeLimits(),
0N/A true,
0N/A altNameCache);
0N/A } else {
0N/A FontManager.registerCompositeFont(
0N/A descriptor.getFaceName(),
0N/A componentFileNames, componentFaceNames,
0N/A descriptor.getCoreComponentCount(),
0N/A descriptor.getExclusionRanges(),
0N/A descriptor.getExclusionRangeLimits(),
0N/A true);
0N/A }
0N/A if (debugFonts) {
0N/A logger.info("registered " + descriptor.getFaceName());
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Notifies graphics environment that the logical font configuration
0N/A * uses the given platform font name. The graphics environment may
0N/A * use this for platform specific initialization.
0N/A */
0N/A protected void addFontToPlatformFontPath(String platformFontName) {
0N/A }
0N/A
0N/A protected void registerPlatformFontsUsedByFontConfiguration() {
0N/A }
0N/A
0N/A /**
0N/A * Determines whether the given font is a logical font.
0N/A */
0N/A public static boolean isLogicalFont(Font f) {
0N/A return FontConfiguration.isLogicalFontFamilyName(f.getFamily());
0N/A }
0N/A
0N/A /**
0N/A * Return the default font configuration.
0N/A */
0N/A public FontConfiguration getFontConfiguration() {
0N/A return fontConfig;
0N/A }
0N/A
0N/A /**
0N/A * Return the bounds of a GraphicsDevice, less its screen insets.
0N/A * See also java.awt.GraphicsEnvironment.getUsableBounds();
0N/A */
0N/A public static Rectangle getUsableBounds(GraphicsDevice gd) {
0N/A GraphicsConfiguration gc = gd.getDefaultConfiguration();
0N/A Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
0N/A Rectangle usableBounds = gc.getBounds();
0N/A
0N/A usableBounds.x += insets.left;
0N/A usableBounds.y += insets.top;
0N/A usableBounds.width -= (insets.left + insets.right);
0N/A usableBounds.height -= (insets.top + insets.bottom);
0N/A
0N/A return usableBounds;
0N/A }
0N/A
0N/A /**
0N/A * This method is provided for internal and exclusive use by Swing.
0N/A * This method should no longer be called, instead directly call
0N/A * FontManager.fontSupportsDefaultEncoding(Font).
0N/A * This method will be removed once Swing is updated to no longer
0N/A * call it.
0N/A */
0N/A public static boolean fontSupportsDefaultEncoding(Font font) {
0N/A return FontManager.fontSupportsDefaultEncoding(font);
0N/A }
0N/A
0N/A public static void useAlternateFontforJALocales() {
0N/A FontManager.useAlternateFontforJALocales();
0N/A }
0N/A
0N/A /*
0N/A * This invocation is not in a privileged block because
0N/A * all privileged operations (reading files and properties)
0N/A * was conducted on the creation of the GE
0N/A */
0N/A public void
0N/A createCompositeFonts(ConcurrentHashMap<String, Font2D> altNameCache,
0N/A boolean preferLocale,
0N/A boolean preferProportional) {
0N/A
0N/A FontConfiguration fontConfig =
0N/A createFontConfiguration(preferLocale, preferProportional);
0N/A initCompositeFonts(fontConfig, altNameCache);
0N/A }
0N/A
0N/A /* If (as we do on X11) need to set a platform font path,
0N/A * then the needed path may be specified by the platform
0N/A * specific FontConfiguration class & data file. Such platforms
0N/A * (ie X11) need to override this method to retrieve this information
0N/A * into suitable data structures.
0N/A */
0N/A protected void getPlatformFontPathFromFontConfig() {
0N/A }
0N/A
0N/A /**
0N/A * From the DisplayChangedListener interface; called
0N/A * when the display mode has been changed.
0N/A */
0N/A public void displayChanged() {
0N/A // notify screens in device array to do display update stuff
0N/A for (GraphicsDevice gd : getScreenDevices()) {
0N/A if (gd instanceof DisplayChangedListener) {
0N/A ((DisplayChangedListener) gd).displayChanged();
0N/A }
0N/A }
0N/A
0N/A // notify SunDisplayChanger list (e.g. VolatileSurfaceManagers and
0N/A // SurfaceDataProxies) about the display change event
0N/A displayChanger.notifyListeners();
0N/A }
0N/A
0N/A /**
0N/A * Part of the DisplayChangedListener interface:
0N/A * propagate this event to listeners
0N/A */
0N/A public void paletteChanged() {
0N/A displayChanger.notifyPaletteChanged();
0N/A }
0N/A
0N/A /*
0N/A * ----DISPLAY CHANGE SUPPORT----
0N/A */
0N/A
0N/A protected SunDisplayChanger displayChanger = new SunDisplayChanger();
0N/A
0N/A /**
0N/A * Add a DisplayChangeListener to be notified when the display settings
0N/A * are changed.
0N/A */
0N/A public void addDisplayChangedListener(DisplayChangedListener client) {
0N/A displayChanger.add(client);
0N/A }
0N/A
0N/A /**
0N/A * Remove a DisplayChangeListener from Win32GraphicsEnvironment
0N/A */
0N/A public void removeDisplayChangedListener(DisplayChangedListener client) {
0N/A displayChanger.remove(client);
0N/A }
0N/A
0N/A /*
0N/A * ----END DISPLAY CHANGE SUPPORT----
0N/A */
0N/A}