/* * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.font; import java.awt.Font;import java.awt.FontFormatException;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.FilenameFilter;import java.io.IOException;import java.io.InputStreamReader;import java.security.AccessController;import java.security.PrivilegedAction;import java.util.ArrayList;import java.util.HashMap;import java.util.HashSet;import java.util.Hashtable;import java.util.Iterator;import java.util.Locale;import java.util.Map;import java.util.NoSuchElementException;import java.util.StringTokenizer;import java.util.TreeMap;import java.util.Vector;import java.util.concurrent.ConcurrentHashMap; import javax.swing.plaf.FontUIResource;import sun.awt.AppContext;import sun.awt.FontConfiguration;import sun.awt.SunToolkit;import sun.java2d.FontSupport;import sun.util.logging.PlatformLogger; /** * The base implementation of the {@link FontManager} interface. It implements * the platform independent, shared parts of OpenJDK's FontManager * implementations. The platform specific parts are declared as abstract * methods that have to be implemented by specific implementations. */public abstract class SunFontManager implements FontSupport, FontManagerForSGE { private static class TTFilter implements FilenameFilter { public boolean accept(File dir,String name) { /* all conveniently have the same suffix length */ int offset = name.length()-4; if (offset <= 0) { /* must be at least A.ttf */ return false; } else { return(name.startsWith(".ttf", offset) || name.startsWith(".TTF", offset) || name.startsWith(".ttc", offset) || name.startsWith(".TTC", offset) || name.startsWith(".otf", offset) || name.startsWith(".OTF", offset)); } } } private static class T1Filter implements FilenameFilter { public boolean accept(File dir,String name) { if (noType1Font) { return false; } /* all conveniently have the same suffix length */ int offset = name.length()-4; if (offset <= 0) { /* must be at least A.pfa */ return false; } else { return(name.startsWith(".pfa", offset) || name.startsWith(".pfb", offset) || name.startsWith(".PFA", offset) || name.startsWith(".PFB", offset)); } } } private static class TTorT1Filter implements FilenameFilter { public boolean accept(File dir, String name) { /* all conveniently have the same suffix length */ int offset = name.length()-4; if (offset <= 0) { /* must be at least A.ttf or A.pfa */ return false; } else { boolean isTT = name.startsWith(".ttf", offset) || name.startsWith(".TTF", offset) || name.startsWith(".ttc", offset) || name.startsWith(".TTC", offset) || name.startsWith(".otf", offset) || name.startsWith(".OTF", offset); if (isTT) { return true; } else if (noType1Font) { return false; } else { return(name.startsWith(".pfa", offset) || name.startsWith(".pfb", offset) || name.startsWith(".PFA", offset) || name.startsWith(".PFB", offset)); } } } } public static final int FONTFORMAT_NONE = -1; public static final int FONTFORMAT_TRUETYPE = 0; public static final int FONTFORMAT_TYPE1 = 1; public static final int FONTFORMAT_T2K = 2; public static final int FONTFORMAT_TTC = 3; public static final int FONTFORMAT_COMPOSITE = 4; public static final int FONTFORMAT_NATIVE = 5; /* Pool of 20 font file channels chosen because some UTF-8 locale * composite fonts can use up to 16 platform fonts (including the * Lucida fall back). This should prevent channel thrashing when * dealing with one of these fonts. * The pool array stores the fonts, rather than directly referencing * the channels, as the font needs to do the open/close work. */ private static final int CHANNELPOOLSIZE = 20; private int lastPoolIndex = 0; private FileFont fontFileCache[] = new FileFont[CHANNELPOOLSIZE]; /* Need to implement a simple linked list scheme for fast * traversal and lookup. * Also want to "fast path" dialog so there's minimal overhead. */ /* There are at exactly 20 composite fonts: 5 faces (but some are not * usually different), in 4 styles. The array may be auto-expanded * later if more are needed, eg for user-defined composites or locale * variants. */ private int maxCompFont = 0; private CompositeFont [] compFonts = new CompositeFont[20]; private ConcurrentHashMap<String, CompositeFont> compositeFonts = new ConcurrentHashMap<String, CompositeFont>(); private ConcurrentHashMap<String, PhysicalFont> physicalFonts = new ConcurrentHashMap<String, PhysicalFont>(); private ConcurrentHashMap<String, PhysicalFont> registeredFonts = new ConcurrentHashMap<String, PhysicalFont>(); /* given a full name find the Font. Remind: there's duplication * here in that this contains the content of compositeFonts + * physicalFonts. */ private ConcurrentHashMap<String, Font2D> fullNameToFont = new ConcurrentHashMap<String, Font2D>(); /* TrueType fonts have localised names. Support searching all * of these before giving up on a name. */ private HashMap<String, TrueTypeFont> localeFullNamesToFont; private PhysicalFont defaultPhysicalFont; static boolean longAddresses; private boolean loaded1dot0Fonts = false; boolean loadedAllFonts = false; boolean loadedAllFontFiles = false; HashMap<String,String> jreFontMap; HashSet<String> jreLucidaFontFiles; String[] jreOtherFontFiles; boolean noOtherJREFontFiles = false; // initial assumption. public static final String lucidaFontName = "Lucida Sans Regular"; public static String jreLibDirName; public static String jreFontDirName; private static HashSet<String> missingFontFiles = null; private String defaultFontName; private String defaultFontFileName; protected HashSet registeredFontFiles = new HashSet(); private ArrayList badFonts; /* fontPath is the location of all fonts on the system, excluding the * JRE's own font directory but including any path specified using the * sun.java2d.fontpath property. Together with that property, it is * initialised by the getPlatformFontPath() method * This call must be followed by a call to registerFontDirs(fontPath) * once any extra debugging path has been appended. */ protected String fontPath; private FontConfiguration fontConfig; /* discoveredAllFonts is set to true when all fonts on the font path are * discovered. This usually also implies opening, validating and * registering, but an implementation may be optimized to avold this. * So see also "loadedAllFontFiles" */ private boolean discoveredAllFonts = false; /* No need to keep consing up new instances - reuse a singleton. * The trade-off is that these objects don't get GC'd. */ private static final FilenameFilter ttFilter = new TTFilter(); private static final FilenameFilter t1Filter = new T1Filter(); private Font[] allFonts; private String[] allFamilies; // cache for default locale only private Locale lastDefaultLocale; public static boolean noType1Font; /* Used to indicate required return type from toArray(..); */ private static String[] STR_ARRAY = new String[0]; /** * Deprecated, unsupported hack - actually invokes a bug! * Left in for a customer, don't remove. */ private boolean usePlatformFontMetrics = false; /** * Returns the global SunFontManager instance. This is similar to * {@link FontManagerFactory#getInstance()} but it returns a * SunFontManager instance instead. This is only used in internal classes * where we can safely assume that a SunFontManager is to be used. * * @return the global SunFontManager instance */ public static SunFontManager getInstance() { FontManager fm = FontManagerFactory.getInstance(); return (SunFontManager) fm; } public FilenameFilter getTrueTypeFilter() { return ttFilter; } public FilenameFilter getType1Filter() { return t1Filter; } @Override public boolean usingPerAppContextComposites() { return _usingPerAppContextComposites; } private void initJREFontMap() { /* Key is familyname+style value as an int. * Value is filename containing the font. * If no mapping exists, it means there is no font file for the style * If the mapping exists but the file doesn't exist in the deferred * list then it means its not installed. * This looks like a lot of code and strings but if it saves even * a single file being opened at JRE start-up there's a big payoff. * Lucida Sans is probably the only important case as the others * are rarely used. Consider removing the other mappings if there's * no evidence they are useful in practice. */ jreFontMap = new HashMap<String,String>(); jreLucidaFontFiles = new HashSet<String>(); if (isOpenJDK()) { return; } /* Lucida Sans Family */ jreFontMap.put("lucida sans0", "LucidaSansRegular.ttf"); jreFontMap.put("lucida sans1", "LucidaSansDemiBold.ttf"); /* Lucida Sans full names (map Bold and DemiBold to same file) */ jreFontMap.put("lucida sans regular0", "LucidaSansRegular.ttf"); jreFontMap.put("lucida sans regular1", "LucidaSansDemiBold.ttf"); jreFontMap.put("lucida sans bold1", "LucidaSansDemiBold.ttf"); jreFontMap.put("lucida sans demibold1", "LucidaSansDemiBold.ttf"); /* Lucida Sans Typewriter Family */ jreFontMap.put("lucida sans typewriter0", "LucidaTypewriterRegular.ttf"); jreFontMap.put("lucida sans typewriter1", "LucidaTypewriterBold.ttf"); /* Typewriter full names (map Bold and DemiBold to same file) */ jreFontMap.put("lucida sans typewriter regular0", "LucidaTypewriter.ttf"); jreFontMap.put("lucida sans typewriter regular1", "LucidaTypewriterBold.ttf"); jreFontMap.put("lucida sans typewriter bold1", "LucidaTypewriterBold.ttf"); jreFontMap.put("lucida sans typewriter demibold1", "LucidaTypewriterBold.ttf"); /* Lucida Bright Family */ jreFontMap.put("lucida bright0", "LucidaBrightRegular.ttf"); jreFontMap.put("lucida bright1", "LucidaBrightDemiBold.ttf"); jreFontMap.put("lucida bright2", "LucidaBrightItalic.ttf"); jreFontMap.put("lucida bright3", "LucidaBrightDemiItalic.ttf"); /* Lucida Bright full names (map Bold and DemiBold to same file) */ jreFontMap.put("lucida bright regular0", "LucidaBrightRegular.ttf"); jreFontMap.put("lucida bright regular1", "LucidaBrightDemiBold.ttf"); jreFontMap.put("lucida bright regular2", "LucidaBrightItalic.ttf"); jreFontMap.put("lucida bright regular3", "LucidaBrightDemiItalic.ttf"); jreFontMap.put("lucida bright bold1", "LucidaBrightDemiBold.ttf"); jreFontMap.put("lucida bright bold3", "LucidaBrightDemiItalic.ttf"); jreFontMap.put("lucida bright demibold1", "LucidaBrightDemiBold.ttf"); jreFontMap.put("lucida bright demibold3","LucidaBrightDemiItalic.ttf"); jreFontMap.put("lucida bright italic2", "LucidaBrightItalic.ttf"); jreFontMap.put("lucida bright italic3", "LucidaBrightDemiItalic.ttf"); jreFontMap.put("lucida bright bold italic3", "LucidaBrightDemiItalic.ttf"); jreFontMap.put("lucida bright demibold italic3", "LucidaBrightDemiItalic.ttf"); for (String ffile : jreFontMap.values()) { jreLucidaFontFiles.add(ffile); } } static { java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Object run() { FontManagerNativeLibrary.load(); // JNI throws an exception if a class/method/field is not found, // so there's no need to do anything explicit here. initIDs(); switch (StrikeCache.nativeAddressSize) { case 8: longAddresses = true; break; case 4: longAddresses = false; break; default: throw new RuntimeException("Unexpected address size"); } noType1Font = "true".equals(System.getProperty("sun.java2d.noType1Font")); jreLibDirName = System.getProperty("java.home","") + File.separator + "lib"; jreFontDirName = jreLibDirName + File.separator + "fonts"; File lucidaFile = new File(jreFontDirName + File.separator + FontUtilities.LUCIDA_FILE_NAME); return null; } }); } public TrueTypeFont getEUDCFont() { // Overridden in Windows. return null; } /* Initialise ptrs used by JNI methods */ private static native void initIDs(); @SuppressWarnings("unchecked") protected SunFontManager() { initJREFontMap(); java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Object run() { File badFontFile = new File(jreFontDirName + File.separator + "badfonts.txt"); if (badFontFile.exists()) { FileInputStream fis = null; try { badFonts = new ArrayList(); fis = new FileInputStream(badFontFile); InputStreamReader isr = new InputStreamReader(fis); BufferedReader br = new BufferedReader(isr); while (true) { String name = br.readLine(); if (name == null) { break; } else { if (FontUtilities.debugFonts()) { FontUtilities.getLogger().warning("read bad font: " + name); } badFonts.add(name); } } } catch (IOException e) { try { if (fis != null) { fis.close(); } } catch (IOException ioe) { } } } /* Here we get the fonts in jre/lib/fonts and register * them so they are always available and preferred over * other fonts. This needs to be registered before the * composite fonts as otherwise some native font that * corresponds may be found as we don't have a way to * handle two fonts of the same name, so the JRE one * must be the first one registered. Pass "true" to * registerFonts method as on-screen these JRE fonts * always go through the T2K rasteriser. */ if (FontUtilities.isLinux) { /* Linux font configuration uses these fonts */ registerFontDir(jreFontDirName); } registerFontsInDir(jreFontDirName, true, Font2D.JRE_RANK, true, false); /* Create the font configuration and get any font path * that might be specified. */ fontConfig = createFontConfiguration(); if (isOpenJDK()) { String[] fontInfo = getDefaultPlatformFont(); defaultFontName = fontInfo[0]; defaultFontFileName = fontInfo[1]; } String extraFontPath = fontConfig.getExtraFontPath(); /* In prior releases the debugging font path replaced * all normally located font directories except for the * JRE fonts dir. This directory is still always located * and placed at the head of the path but as an * augmentation to the previous behaviour the * changes below allow you to additionally append to * the font path by starting with append: or prepend by * starting with a prepend: sign. Eg: to append * -Dsun.java2d.fontpath=append:/usr/local/myfonts * and to prepend * -Dsun.java2d.fontpath=prepend:/usr/local/myfonts Disp * * If there is an appendedfontpath it in the font * configuration it is used instead of searching the * system for dirs. * The behaviour of append and prepend is then similar * to the normal case. ie it goes after what * you prepend and * before what you append. If the * sun.java2d.fontpath property is used, but it * neither the append or prepend syntaxes is used then * as except for the JRE dir the path is replaced and it * is up to you to make sure that all the right * directories are located. This is platform and * locale-specific so its almost impossible to get * right, so it should be used with caution. */ boolean prependToPath = false; boolean appendToPath = false; String dbgFontPath = System.getProperty("sun.java2d.fontpath"); if (dbgFontPath != null) { if (dbgFontPath.startsWith("prepend:")) { prependToPath = true; dbgFontPath = dbgFontPath.substring("prepend:".length()); } else if (dbgFontPath.startsWith("append:")) { appendToPath = true; dbgFontPath = dbgFontPath.substring("append:".length()); } } if (FontUtilities.debugFonts()) { PlatformLogger logger = FontUtilities.getLogger(); logger.info("JRE font directory: " + jreFontDirName); logger.info("Extra font path: " + extraFontPath); logger.info("Debug font path: " + dbgFontPath); } if (dbgFontPath != null) { /* In debugging mode we register all the paths * Caution: this is a very expensive call on Solaris:- */ fontPath = getPlatformFontPath(noType1Font); if (extraFontPath != null) { fontPath = extraFontPath + File.pathSeparator + fontPath; } if (appendToPath) { fontPath = fontPath + File.pathSeparator + dbgFontPath; } else if (prependToPath) { fontPath = dbgFontPath + File.pathSeparator + fontPath;Lines 1–500 of 3912. Load more
/* * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.font; import java.awt.Font; import java.awt.FontFormatException; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStreamReader; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.NoSuchElementException; import java.util.StringTokenizer; import java.util.TreeMap; import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; import javax.swing.plaf.FontUIResource; import sun.awt.AppContext; import sun.awt.FontConfiguration; import sun.awt.SunToolkit; import sun.java2d.FontSupport; import sun.util.logging.PlatformLogger; /** * The base implementation of the {@link FontManager} interface. It implements * the platform independent, shared parts of OpenJDK's FontManager * implementations. The platform specific parts are declared as abstract * methods that have to be implemented by specific implementations. */ public abstract class SunFontManager implements FontSupport, FontManagerForSGE { private static class TTFilter implements FilenameFilter { public boolean accept(File dir,String name) { /* all conveniently have the same suffix length */ int offset = name.length()-4; if (offset <= 0) { /* must be at least A.ttf */ return false; } else { return(name.startsWith(".ttf", offset) || name.startsWith(".TTF", offset) || name.startsWith(".ttc", offset) || name.startsWith(".TTC", offset) || name.startsWith(".otf", offset) || name.startsWith(".OTF", offset)); } } } private static class T1Filter implements FilenameFilter { public boolean accept(File dir,String name) { if (noType1Font) { return false; } /* all conveniently have the same suffix length */ int offset = name.length()-4; if (offset <= 0) { /* must be at least A.pfa */ return false; } else { return(name.startsWith(".pfa", offset) || name.startsWith(".pfb", offset) || name.startsWith(".PFA", offset) || name.startsWith(".PFB", offset)); } } } private static class TTorT1Filter implements FilenameFilter { public boolean accept(File dir, String name) { /* all conveniently have the same suffix length */ int offset = name.length()-4; if (offset <= 0) { /* must be at least A.ttf or A.pfa */ return false; } else { boolean isTT = name.startsWith(".ttf", offset) || name.startsWith(".TTF", offset) || name.startsWith(".ttc", offset) || name.startsWith(".TTC", offset) || name.startsWith(".otf", offset) || name.startsWith(".OTF", offset); if (isTT) { return true; } else if (noType1Font) { return false; } else { return(name.startsWith(".pfa", offset) || name.startsWith(".pfb", offset) || name.startsWith(".PFA", offset) || name.startsWith(".PFB", offset)); } } } } public static final int FONTFORMAT_NONE = -1; public static final int FONTFORMAT_TRUETYPE = 0; public static final int FONTFORMAT_TYPE1 = 1; public static final int FONTFORMAT_T2K = 2; public static final int FONTFORMAT_TTC = 3; public static final int FONTFORMAT_COMPOSITE = 4; public static final int FONTFORMAT_NATIVE = 5; /* Pool of 20 font file channels chosen because some UTF-8 locale * composite fonts can use up to 16 platform fonts (including the * Lucida fall back). This should prevent channel thrashing when * dealing with one of these fonts. * The pool array stores the fonts, rather than directly referencing * the channels, as the font needs to do the open/close work. */ private static final int CHANNELPOOLSIZE = 20; private int lastPoolIndex = 0; private FileFont fontFileCache[] = new FileFont[CHANNELPOOLSIZE]; /* Need to implement a simple linked list scheme for fast * traversal and lookup. * Also want to "fast path" dialog so there's minimal overhead. */ /* There are at exactly 20 composite fonts: 5 faces (but some are not * usually different), in 4 styles. The array may be auto-expanded * later if more are needed, eg for user-defined composites or locale * variants. */ private int maxCompFont = 0; private CompositeFont [] compFonts = new CompositeFont[20]; private ConcurrentHashMap<String, CompositeFont> compositeFonts = new ConcurrentHashMap<String, CompositeFont>(); private ConcurrentHashMap<String, PhysicalFont> physicalFonts = new ConcurrentHashMap<String, PhysicalFont>(); private ConcurrentHashMap<String, PhysicalFont> registeredFonts = new ConcurrentHashMap<String, PhysicalFont>(); /* given a full name find the Font. Remind: there's duplication * here in that this contains the content of compositeFonts + * physicalFonts. */ private ConcurrentHashMap<String, Font2D> fullNameToFont = new ConcurrentHashMap<String, Font2D>(); /* TrueType fonts have localised names. Support searching all * of these before giving up on a name. */ private HashMap<String, TrueTypeFont> localeFullNamesToFont; private PhysicalFont defaultPhysicalFont; static boolean longAddresses; private boolean loaded1dot0Fonts = false; boolean loadedAllFonts = false; boolean loadedAllFontFiles = false; HashMap<String,String> jreFontMap; HashSet<String> jreLucidaFontFiles; String[] jreOtherFontFiles; boolean noOtherJREFontFiles = false; // initial assumption. public static final String lucidaFontName = "Lucida Sans Regular"; public static String jreLibDirName; public static String jreFontDirName; private static HashSet<String> missingFontFiles = null; private String defaultFontName; private String defaultFontFileName; protected HashSet registeredFontFiles = new HashSet(); private ArrayList badFonts; /* fontPath is the location of all fonts on the system, excluding the * JRE's own font directory but including any path specified using the * sun.java2d.fontpath property. Together with that property, it is * initialised by the getPlatformFontPath() method * This call must be followed by a call to registerFontDirs(fontPath) * once any extra debugging path has been appended. */ protected String fontPath; private FontConfiguration fontConfig; /* discoveredAllFonts is set to true when all fonts on the font path are * discovered. This usually also implies opening, validating and * registering, but an implementation may be optimized to avold this. * So see also "loadedAllFontFiles" */ private boolean discoveredAllFonts = false; /* No need to keep consing up new instances - reuse a singleton. * The trade-off is that these objects don't get GC'd. */ private static final FilenameFilter ttFilter = new TTFilter(); private static final FilenameFilter t1Filter = new T1Filter(); private Font[] allFonts; private String[] allFamilies; // cache for default locale only private Locale lastDefaultLocale; public static boolean noType1Font; /* Used to indicate required return type from toArray(..); */ private static String[] STR_ARRAY = new String[0]; /** * Deprecated, unsupported hack - actually invokes a bug! * Left in for a customer, don't remove. */ private boolean usePlatformFontMetrics = false; /** * Returns the global SunFontManager instance. This is similar to * {@link FontManagerFactory#getInstance()} but it returns a * SunFontManager instance instead. This is only used in internal classes * where we can safely assume that a SunFontManager is to be used. * * @return the global SunFontManager instance */ public static SunFontManager getInstance() { FontManager fm = FontManagerFactory.getInstance(); return (SunFontManager) fm; } public FilenameFilter getTrueTypeFilter() { return ttFilter; } public FilenameFilter getType1Filter() { return t1Filter; } @Override public boolean usingPerAppContextComposites() { return _usingPerAppContextComposites; } private void initJREFontMap() { /* Key is familyname+style value as an int. * Value is filename containing the font. * If no mapping exists, it means there is no font file for the style * If the mapping exists but the file doesn't exist in the deferred * list then it means its not installed. * This looks like a lot of code and strings but if it saves even * a single file being opened at JRE start-up there's a big payoff. * Lucida Sans is probably the only important case as the others * are rarely used. Consider removing the other mappings if there's * no evidence they are useful in practice. */ jreFontMap = new HashMap<String,String>(); jreLucidaFontFiles = new HashSet<String>(); if (isOpenJDK()) { return; } /* Lucida Sans Family */ jreFontMap.put("lucida sans0", "LucidaSansRegular.ttf"); jreFontMap.put("lucida sans1", "LucidaSansDemiBold.ttf"); /* Lucida Sans full names (map Bold and DemiBold to same file) */ jreFontMap.put("lucida sans regular0", "LucidaSansRegular.ttf"); jreFontMap.put("lucida sans regular1", "LucidaSansDemiBold.ttf"); jreFontMap.put("lucida sans bold1", "LucidaSansDemiBold.ttf"); jreFontMap.put("lucida sans demibold1", "LucidaSansDemiBold.ttf"); /* Lucida Sans Typewriter Family */ jreFontMap.put("lucida sans typewriter0", "LucidaTypewriterRegular.ttf"); jreFontMap.put("lucida sans typewriter1", "LucidaTypewriterBold.ttf"); /* Typewriter full names (map Bold and DemiBold to same file) */ jreFontMap.put("lucida sans typewriter regular0", "LucidaTypewriter.ttf"); jreFontMap.put("lucida sans typewriter regular1", "LucidaTypewriterBold.ttf"); jreFontMap.put("lucida sans typewriter bold1", "LucidaTypewriterBold.ttf"); jreFontMap.put("lucida sans typewriter demibold1", "LucidaTypewriterBold.ttf"); /* Lucida Bright Family */ jreFontMap.put("lucida bright0", "LucidaBrightRegular.ttf"); jreFontMap.put("lucida bright1", "LucidaBrightDemiBold.ttf"); jreFontMap.put("lucida bright2", "LucidaBrightItalic.ttf"); jreFontMap.put("lucida bright3", "LucidaBrightDemiItalic.ttf"); /* Lucida Bright full names (map Bold and DemiBold to same file) */ jreFontMap.put("lucida bright regular0", "LucidaBrightRegular.ttf"); jreFontMap.put("lucida bright regular1", "LucidaBrightDemiBold.ttf"); jreFontMap.put("lucida bright regular2", "LucidaBrightItalic.ttf"); jreFontMap.put("lucida bright regular3", "LucidaBrightDemiItalic.ttf"); jreFontMap.put("lucida bright bold1", "LucidaBrightDemiBold.ttf"); jreFontMap.put("lucida bright bold3", "LucidaBrightDemiItalic.ttf"); jreFontMap.put("lucida bright demibold1", "LucidaBrightDemiBold.ttf"); jreFontMap.put("lucida bright demibold3","LucidaBrightDemiItalic.ttf"); jreFontMap.put("lucida bright italic2", "LucidaBrightItalic.ttf"); jreFontMap.put("lucida bright italic3", "LucidaBrightDemiItalic.ttf"); jreFontMap.put("lucida bright bold italic3", "LucidaBrightDemiItalic.ttf"); jreFontMap.put("lucida bright demibold italic3", "LucidaBrightDemiItalic.ttf"); for (String ffile : jreFontMap.values()) { jreLucidaFontFiles.add(ffile); } } static { java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Object run() { FontManagerNativeLibrary.load(); // JNI throws an exception if a class/method/field is not found, // so there's no need to do anything explicit here. initIDs(); switch (StrikeCache.nativeAddressSize) { case 8: longAddresses = true; break; case 4: longAddresses = false; break; default: throw new RuntimeException("Unexpected address size"); } noType1Font = "true".equals(System.getProperty("sun.java2d.noType1Font")); jreLibDirName = System.getProperty("java.home","") + File.separator + "lib"; jreFontDirName = jreLibDirName + File.separator + "fonts"; File lucidaFile = new File(jreFontDirName + File.separator + FontUtilities.LUCIDA_FILE_NAME); return null; } }); } public TrueTypeFont getEUDCFont() { // Overridden in Windows. return null; } /* Initialise ptrs used by JNI methods */ private static native void initIDs(); @SuppressWarnings("unchecked") protected SunFontManager() { initJREFontMap(); java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Object run() { File badFontFile = new File(jreFontDirName + File.separator + "badfonts.txt"); if (badFontFile.exists()) { FileInputStream fis = null; try { badFonts = new ArrayList(); fis = new FileInputStream(badFontFile); InputStreamReader isr = new InputStreamReader(fis); BufferedReader br = new BufferedReader(isr); while (true) { String name = br.readLine(); if (name == null) { break; } else { if (FontUtilities.debugFonts()) { FontUtilities.getLogger().warning("read bad font: " + name); } badFonts.add(name); } } } catch (IOException e) { try { if (fis != null) { fis.close(); } } catch (IOException ioe) { } } } /* Here we get the fonts in jre/lib/fonts and register * them so they are always available and preferred over * other fonts. This needs to be registered before the * composite fonts as otherwise some native font that * corresponds may be found as we don't have a way to * handle two fonts of the same name, so the JRE one * must be the first one registered. Pass "true" to * registerFonts method as on-screen these JRE fonts * always go through the T2K rasteriser. */ if (FontUtilities.isLinux) { /* Linux font configuration uses these fonts */ registerFontDir(jreFontDirName); } registerFontsInDir(jreFontDirName, true, Font2D.JRE_RANK, true, false); /* Create the font configuration and get any font path * that might be specified. */ fontConfig = createFontConfiguration(); if (isOpenJDK()) { String[] fontInfo = getDefaultPlatformFont(); defaultFontName = fontInfo[0]; defaultFontFileName = fontInfo[1]; } String extraFontPath = fontConfig.getExtraFontPath(); /* In prior releases the debugging font path replaced * all normally located font directories except for the * JRE fonts dir. This directory is still always located * and placed at the head of the path but as an * augmentation to the previous behaviour the * changes below allow you to additionally append to * the font path by starting with append: or prepend by * starting with a prepend: sign. Eg: to append * -Dsun.java2d.fontpath=append:/usr/local/myfonts * and to prepend * -Dsun.java2d.fontpath=prepend:/usr/local/myfonts Disp * * If there is an appendedfontpath it in the font * configuration it is used instead of searching the * system for dirs. * The behaviour of append and prepend is then similar * to the normal case. ie it goes after what * you prepend and * before what you append. If the * sun.java2d.fontpath property is used, but it * neither the append or prepend syntaxes is used then * as except for the JRE dir the path is replaced and it * is up to you to make sure that all the right * directories are located. This is platform and * locale-specific so its almost impossible to get * right, so it should be used with caution. */ boolean prependToPath = false; boolean appendToPath = false; String dbgFontPath = System.getProperty("sun.java2d.fontpath"); if (dbgFontPath != null) { if (dbgFontPath.startsWith("prepend:")) { prependToPath = true; dbgFontPath = dbgFontPath.substring("prepend:".length()); } else if (dbgFontPath.startsWith("append:")) { appendToPath = true; dbgFontPath = dbgFontPath.substring("append:".length()); } } if (FontUtilities.debugFonts()) { PlatformLogger logger = FontUtilities.getLogger(); logger.info("JRE font directory: " + jreFontDirName); logger.info("Extra font path: " + extraFontPath); logger.info("Debug font path: " + dbgFontPath); } if (dbgFontPath != null) { /* In debugging mode we register all the paths * Caution: this is a very expensive call on Solaris:- */ fontPath = getPlatformFontPath(noType1Font); if (extraFontPath != null) { fontPath = extraFontPath + File.pathSeparator + fontPath; } if (appendToPath) { fontPath = fontPath + File.pathSeparator + dbgFontPath; } else if (prependToPath) { fontPath = dbgFontPath + File.pathSeparator + fontPath;