/* * Copyright (c) 2000, 2010, 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.awt; import java.awt.Font;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.InputStream;import java.io.IOException;import java.io.OutputStream;import java.nio.charset.Charset;import java.nio.charset.CharsetEncoder;import java.security.AccessController;import java.security.PrivilegedAction;import java.util.Arrays;import java.util.HashMap;import java.util.HashSet;import java.util.Hashtable;import java.util.Locale;import java.util.Map.Entry;import java.util.Properties;import java.util.Set;import java.util.Vector;import sun.font.CompositeFontDescriptor;import sun.font.SunFontManager;import sun.font.FontManagerFactory;import sun.font.FontUtilities;import sun.util.logging.PlatformLogger; /** * Provides the definitions of the five logical fonts: Serif, SansSerif, * Monospaced, Dialog, and DialogInput. The necessary information * is obtained from fontconfig files. */public abstract class FontConfiguration { //static global runtime env protected static String osVersion; protected static String osName; protected static String encoding; // canonical name of default nio charset protected static Locale startupLocale = null; protected static Hashtable localeMap = null; private static FontConfiguration fontConfig; private static PlatformLogger logger; protected static boolean isProperties = true; protected SunFontManager fontManager; protected boolean preferLocaleFonts; protected boolean preferPropFonts; private File fontConfigFile; private boolean foundOsSpecificFile; private boolean inited; private String javaLib; /* A default FontConfiguration must be created before an alternate * one to ensure proper static initialisation takes place. */ public FontConfiguration(SunFontManager fm) { if (FontUtilities.debugFonts()) { FontUtilities.getLogger() .info("Creating standard Font Configuration"); } if (FontUtilities.debugFonts() && logger == null) { logger = PlatformLogger.getLogger("sun.awt.FontConfiguration"); } fontManager = fm; setOsNameAndVersion(); /* static initialization */ setEncoding(); /* static initialization */ /* Separating out the file location from the rest of the * initialisation, so the caller has the option of doing * something else if a suitable file isn't found. */ findFontConfigFile(); } public synchronized boolean init() { if (!inited) { this.preferLocaleFonts = false; this.preferPropFonts = false; setFontConfiguration(); readFontConfigFile(fontConfigFile); initFontConfig(); inited = true; } return true; } public FontConfiguration(SunFontManager fm, boolean preferLocaleFonts, boolean preferPropFonts) { fontManager = fm; if (FontUtilities.debugFonts()) { FontUtilities.getLogger() .info("Creating alternate Font Configuration"); } this.preferLocaleFonts = preferLocaleFonts; this.preferPropFonts = preferPropFonts; /* fontConfig should be initialised by default constructor, and * its data tables can be shared, since readFontConfigFile doesn't * update any other state. Also avoid a doPrivileged block. */ initFontConfig(); } /** * Fills in this instance's osVersion and osName members. By * default uses the system properties os.name and os.version; * subclasses may override. */ protected void setOsNameAndVersion() { osName = System.getProperty("os.name"); osVersion = System.getProperty("os.version"); } private void setEncoding() { encoding = Charset.defaultCharset().name(); startupLocale = SunToolkit.getStartupLocale(); } ///////////////////////////////////////////////////////////////////// // methods for loading the FontConfig file // ///////////////////////////////////////////////////////////////////// public boolean foundOsSpecificFile() { return foundOsSpecificFile; } /* Smoke test to see if we can trust this configuration by testing if * the first slot of a composite font maps to an installed file. */ public boolean fontFilesArePresent() { init(); short fontNameID = compFontNameIDs[0][0][0]; short fileNameID = getComponentFileID(fontNameID); final String fileName = mapFileName(getComponentFileName(fileNameID)); Boolean exists = (Boolean)java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Object run() { try { File f = new File(fileName); return Boolean.valueOf(f.exists()); } catch (Exception e) { return false; } } }); return exists.booleanValue(); } private void findFontConfigFile() { foundOsSpecificFile = true; // default assumption. String javaHome = System.getProperty("java.home"); if (javaHome == null) { throw new Error("java.home property not set"); } javaLib = javaHome + File.separator + "lib"; String userConfigFile = System.getProperty("sun.awt.fontconfig"); if (userConfigFile != null) { fontConfigFile = new File(userConfigFile); } else { fontConfigFile = findFontConfigFile(javaLib); } } private void readFontConfigFile(File f) { /* This is invoked here as readFontConfigFile is only invoked * once per VM, and always in a privileged context, thus the * directory containing installed fall back fonts is accessed * from this context */ getInstalledFallbackFonts(javaLib); if (f != null) { try { FileInputStream in = new FileInputStream(f.getPath()); if (isProperties) { loadProperties(in); } else { loadBinary(in); } in.close(); if (FontUtilities.debugFonts()) { logger.config("Read logical font configuration from " + f); } } catch (IOException e) { if (FontUtilities.debugFonts()) { logger.config("Failed to read logical font configuration from " + f); } } } String version = getVersion(); if (!"1".equals(version) && FontUtilities.debugFonts()) { logger.config("Unsupported fontconfig version: " + version); } } protected void getInstalledFallbackFonts(String javaLib) { String fallbackDirName = javaLib + File.separator + "fonts" + File.separator + "fallback"; File fallbackDir = new File(fallbackDirName); if (fallbackDir.exists() && fallbackDir.isDirectory()) { String[] ttfs = fallbackDir.list(fontManager.getTrueTypeFilter()); String[] t1s = fallbackDir.list(fontManager.getType1Filter()); int numTTFs = (ttfs == null) ? 0 : ttfs.length; int numT1s = (t1s == null) ? 0 : t1s.length; int len = numTTFs + numT1s; if (numTTFs + numT1s == 0) { return; } installedFallbackFontFiles = new String[len]; for (int i=0; i<numTTFs; i++) { installedFallbackFontFiles[i] = fallbackDir + File.separator + ttfs[i]; } for (int i=0; i<numT1s; i++) { installedFallbackFontFiles[i+numTTFs] = fallbackDir + File.separator + t1s[i]; } fontManager.registerFontsInDir(fallbackDirName); } } private File findImpl(String fname) { File f = new File(fname + ".properties"); if (f.canRead()) { isProperties = true; return f; } f = new File(fname + ".bfc"); if (f.canRead()) { isProperties = false; return f; } return null; } private File findFontConfigFile(String javaLib) { String baseName = javaLib + File.separator + "fontconfig"; File configFile; if (osVersion != null && osName != null) { configFile = findImpl(baseName + "." + osName + "." + osVersion); if (configFile != null) { return configFile; } } if (osName != null) { configFile = findImpl(baseName + "." + osName); if (configFile != null) { return configFile; } } if (osVersion != null) { configFile = findImpl(baseName + "." + osVersion); if (configFile != null) { return configFile; } } foundOsSpecificFile = false; configFile = findImpl(baseName); if (configFile != null) { return configFile; } return null; } /* Initialize the internal data tables from binary format font * configuration file. */ public static void loadBinary(InputStream inStream) throws IOException { DataInputStream in = new DataInputStream(inStream); head = readShortTable(in, HEAD_LENGTH); int[] tableSizes = new int[INDEX_TABLEEND]; for (int i = 0; i < INDEX_TABLEEND; i++) { tableSizes[i] = head[i + 1] - head[i]; } table_scriptIDs = readShortTable(in, tableSizes[INDEX_scriptIDs]); table_scriptFonts = readShortTable(in, tableSizes[INDEX_scriptFonts]); table_elcIDs = readShortTable(in, tableSizes[INDEX_elcIDs]); table_sequences = readShortTable(in, tableSizes[INDEX_sequences]); table_fontfileNameIDs = readShortTable(in, tableSizes[INDEX_fontfileNameIDs]); table_componentFontNameIDs = readShortTable(in, tableSizes[INDEX_componentFontNameIDs]); table_filenames = readShortTable(in, tableSizes[INDEX_filenames]); table_awtfontpaths = readShortTable(in, tableSizes[INDEX_awtfontpaths]); table_exclusions = readShortTable(in, tableSizes[INDEX_exclusions]); table_proportionals = readShortTable(in, tableSizes[INDEX_proportionals]); table_scriptFontsMotif = readShortTable(in, tableSizes[INDEX_scriptFontsMotif]); table_alphabeticSuffix = readShortTable(in, tableSizes[INDEX_alphabeticSuffix]); table_stringIDs = readShortTable(in, tableSizes[INDEX_stringIDs]); //StringTable cache stringCache = new String[table_stringIDs.length + 1]; int len = tableSizes[INDEX_stringTable]; byte[] bb = new byte[len * 2]; table_stringTable = new char[len]; in.read(bb); int i = 0, j = 0; while (i < len) { table_stringTable[i++] = (char)(bb[j++] << 8 | (bb[j++] & 0xff)); } if (verbose) { dump(); } } /* Generate a binary format font configuration from internal data * tables. */ public static void saveBinary(OutputStream out) throws IOException { sanityCheck(); DataOutputStream dataOut = new DataOutputStream(out); writeShortTable(dataOut, head); writeShortTable(dataOut, table_scriptIDs); writeShortTable(dataOut, table_scriptFonts); writeShortTable(dataOut, table_elcIDs); writeShortTable(dataOut, table_sequences); writeShortTable(dataOut, table_fontfileNameIDs); writeShortTable(dataOut, table_componentFontNameIDs); writeShortTable(dataOut, table_filenames); writeShortTable(dataOut, table_awtfontpaths); writeShortTable(dataOut, table_exclusions); writeShortTable(dataOut, table_proportionals); writeShortTable(dataOut, table_scriptFontsMotif); writeShortTable(dataOut, table_alphabeticSuffix); writeShortTable(dataOut, table_stringIDs); //stringTable dataOut.writeChars(new String(table_stringTable)); out.close(); if (verbose) { dump(); } } //private static boolean loadingProperties; private static short stringIDNum; private static short[] stringIDs; private static StringBuilder stringTable; public static void loadProperties(InputStream in) throws IOException { //loadingProperties = true; //StringID starts from "1", "0" is reserved for "not defined" stringIDNum = 1; stringIDs = new short[1000]; stringTable = new StringBuilder(4096); if (verbose && logger == null) { logger = PlatformLogger.getLogger("sun.awt.FontConfiguration"); } new PropertiesHandler().load(in); //loadingProperties = false; stringIDs = null; stringTable = null; } ///////////////////////////////////////////////////////////////////// // methods for initializing the FontConfig // ///////////////////////////////////////////////////////////////////// /** * set initLocale, initEncoding and initELC for this FontConfig object * currently we just simply use the startup locale and encoding */ private void initFontConfig() { initLocale = startupLocale; initEncoding = encoding; if (preferLocaleFonts && !willReorderForStartupLocale()) { preferLocaleFonts = false; } initELC = getInitELC(); initAllComponentFonts(); } //"ELC" stands for "Encoding.Language.Country". This method returns //the ID of the matched elc setting of "initLocale" in elcIDs table. //If no match is found, it returns the default ID, which is //"NULL.NULL.NULL" in elcIDs table. private short getInitELC() { if (initELC != -1) { return initELC; } HashMap <String, Integer> elcIDs = new HashMap<String, Integer>(); for (int i = 0; i < table_elcIDs.length; i++) { elcIDs.put(getString(table_elcIDs[i]), i); } String language = initLocale.getLanguage(); String country = initLocale.getCountry(); String elc; if (elcIDs.containsKey(elc=initEncoding + "." + language + "." + country) || elcIDs.containsKey(elc=initEncoding + "." + language) || elcIDs.containsKey(elc=initEncoding)) { initELC = elcIDs.get(elc).shortValue(); } else { initELC = elcIDs.get("NULL.NULL.NULL").shortValue(); } int i = 0; while (i < table_alphabeticSuffix.length) { if (initELC == table_alphabeticSuffix[i]) { alphabeticSuffix = getString(table_alphabeticSuffix[i + 1]); return initELC; } i += 2; } return initELC; } public static boolean verbose; private short initELC = -1; private Locale initLocale; private String initEncoding; private String alphabeticSuffix; private short[][][] compFontNameIDs = new short[NUM_FONTS][NUM_STYLES][]; private int[][][] compExclusions = new int[NUM_FONTS][][]; private int[] compCoreNum = new int[NUM_FONTS]; private Set<Short> coreFontNameIDs = new HashSet<Short>(); private Set<Short> fallbackFontNameIDs = new HashSet<Short>(); private void initAllComponentFonts() { short[] fallbackScripts = getFallbackScripts(); for (int fontIndex = 0; fontIndex < NUM_FONTS; fontIndex++) { short[] coreScripts = getCoreScripts(fontIndex); compCoreNum[fontIndex] = coreScripts.length; /* System.out.println("coreScriptID=" + table_sequences[initELC * 5 + fontIndex]); for (int i = 0; i < coreScripts.length; i++) { System.out.println(" " + i + " :" + getString(table_scriptIDs[coreScripts[i]])); } */ //init exclusionRanges int[][] exclusions = new int[coreScripts.length][]; for (int i = 0; i < coreScripts.length; i++) { exclusions[i] = getExclusionRanges(coreScripts[i]); } compExclusions[fontIndex] = exclusions; //init componentFontNames for (int styleIndex = 0; styleIndex < NUM_STYLES; styleIndex++) { int index; short[] nameIDs = new short[coreScripts.length + fallbackScripts.length]; //core for (index = 0; index < coreScripts.length; index++) { nameIDs[index] = getComponentFontID(coreScripts[index], fontIndex, styleIndex); if (preferLocaleFonts && localeMap != null && fontManager.usingAlternateFontforJALocales()) { nameIDs[index] = remapLocaleMap(fontIndex, styleIndex, coreScripts[index], nameIDs[index]); } if (preferPropFonts) { nameIDs[index] = remapProportional(fontIndex, nameIDs[index]); } //System.out.println("nameid=" + nameIDs[index]); coreFontNameIDs.add(nameIDs[index]); } //fallback for (int i = 0; i < fallbackScripts.length; i++) { short id = getComponentFontID(fallbackScripts[i], fontIndex, styleIndex); if (preferLocaleFonts && localeMap != null && fontManager.usingAlternateFontforJALocales()) { id = remapLocaleMap(fontIndex, styleIndex, fallbackScripts[i], id); } if (preferPropFonts) { id = remapProportional(fontIndex, id); } if (contains(nameIDs, id, index)) { continue;Lines 1–500 of 2272. Load more
/* * Copyright (c) 2000, 2010, 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.awt; import java.awt.Font; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.Locale; import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import java.util.Vector; import sun.font.CompositeFontDescriptor; import sun.font.SunFontManager; import sun.font.FontManagerFactory; import sun.font.FontUtilities; import sun.util.logging.PlatformLogger; /** * Provides the definitions of the five logical fonts: Serif, SansSerif, * Monospaced, Dialog, and DialogInput. The necessary information * is obtained from fontconfig files. */ public abstract class FontConfiguration { //static global runtime env protected static String osVersion; protected static String osName; protected static String encoding; // canonical name of default nio charset protected static Locale startupLocale = null; protected static Hashtable localeMap = null; private static FontConfiguration fontConfig; private static PlatformLogger logger; protected static boolean isProperties = true; protected SunFontManager fontManager; protected boolean preferLocaleFonts; protected boolean preferPropFonts; private File fontConfigFile; private boolean foundOsSpecificFile; private boolean inited; private String javaLib; /* A default FontConfiguration must be created before an alternate * one to ensure proper static initialisation takes place. */ public FontConfiguration(SunFontManager fm) { if (FontUtilities.debugFonts()) { FontUtilities.getLogger() .info("Creating standard Font Configuration"); } if (FontUtilities.debugFonts() && logger == null) { logger = PlatformLogger.getLogger("sun.awt.FontConfiguration"); } fontManager = fm; setOsNameAndVersion(); /* static initialization */ setEncoding(); /* static initialization */ /* Separating out the file location from the rest of the * initialisation, so the caller has the option of doing * something else if a suitable file isn't found. */ findFontConfigFile(); } public synchronized boolean init() { if (!inited) { this.preferLocaleFonts = false; this.preferPropFonts = false; setFontConfiguration(); readFontConfigFile(fontConfigFile); initFontConfig(); inited = true; } return true; } public FontConfiguration(SunFontManager fm, boolean preferLocaleFonts, boolean preferPropFonts) { fontManager = fm; if (FontUtilities.debugFonts()) { FontUtilities.getLogger() .info("Creating alternate Font Configuration"); } this.preferLocaleFonts = preferLocaleFonts; this.preferPropFonts = preferPropFonts; /* fontConfig should be initialised by default constructor, and * its data tables can be shared, since readFontConfigFile doesn't * update any other state. Also avoid a doPrivileged block. */ initFontConfig(); } /** * Fills in this instance's osVersion and osName members. By * default uses the system properties os.name and os.version; * subclasses may override. */ protected void setOsNameAndVersion() { osName = System.getProperty("os.name"); osVersion = System.getProperty("os.version"); } private void setEncoding() { encoding = Charset.defaultCharset().name(); startupLocale = SunToolkit.getStartupLocale(); } ///////////////////////////////////////////////////////////////////// // methods for loading the FontConfig file // ///////////////////////////////////////////////////////////////////// public boolean foundOsSpecificFile() { return foundOsSpecificFile; } /* Smoke test to see if we can trust this configuration by testing if * the first slot of a composite font maps to an installed file. */ public boolean fontFilesArePresent() { init(); short fontNameID = compFontNameIDs[0][0][0]; short fileNameID = getComponentFileID(fontNameID); final String fileName = mapFileName(getComponentFileName(fileNameID)); Boolean exists = (Boolean)java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Object run() { try { File f = new File(fileName); return Boolean.valueOf(f.exists()); } catch (Exception e) { return false; } } }); return exists.booleanValue(); } private void findFontConfigFile() { foundOsSpecificFile = true; // default assumption. String javaHome = System.getProperty("java.home"); if (javaHome == null) { throw new Error("java.home property not set"); } javaLib = javaHome + File.separator + "lib"; String userConfigFile = System.getProperty("sun.awt.fontconfig"); if (userConfigFile != null) { fontConfigFile = new File(userConfigFile); } else { fontConfigFile = findFontConfigFile(javaLib); } } private void readFontConfigFile(File f) { /* This is invoked here as readFontConfigFile is only invoked * once per VM, and always in a privileged context, thus the * directory containing installed fall back fonts is accessed * from this context */ getInstalledFallbackFonts(javaLib); if (f != null) { try { FileInputStream in = new FileInputStream(f.getPath()); if (isProperties) { loadProperties(in); } else { loadBinary(in); } in.close(); if (FontUtilities.debugFonts()) { logger.config("Read logical font configuration from " + f); } } catch (IOException e) { if (FontUtilities.debugFonts()) { logger.config("Failed to read logical font configuration from " + f); } } } String version = getVersion(); if (!"1".equals(version) && FontUtilities.debugFonts()) { logger.config("Unsupported fontconfig version: " + version); } } protected void getInstalledFallbackFonts(String javaLib) { String fallbackDirName = javaLib + File.separator + "fonts" + File.separator + "fallback"; File fallbackDir = new File(fallbackDirName); if (fallbackDir.exists() && fallbackDir.isDirectory()) { String[] ttfs = fallbackDir.list(fontManager.getTrueTypeFilter()); String[] t1s = fallbackDir.list(fontManager.getType1Filter()); int numTTFs = (ttfs == null) ? 0 : ttfs.length; int numT1s = (t1s == null) ? 0 : t1s.length; int len = numTTFs + numT1s; if (numTTFs + numT1s == 0) { return; } installedFallbackFontFiles = new String[len]; for (int i=0; i<numTTFs; i++) { installedFallbackFontFiles[i] = fallbackDir + File.separator + ttfs[i]; } for (int i=0; i<numT1s; i++) { installedFallbackFontFiles[i+numTTFs] = fallbackDir + File.separator + t1s[i]; } fontManager.registerFontsInDir(fallbackDirName); } } private File findImpl(String fname) { File f = new File(fname + ".properties"); if (f.canRead()) { isProperties = true; return f; } f = new File(fname + ".bfc"); if (f.canRead()) { isProperties = false; return f; } return null; } private File findFontConfigFile(String javaLib) { String baseName = javaLib + File.separator + "fontconfig"; File configFile; if (osVersion != null && osName != null) { configFile = findImpl(baseName + "." + osName + "." + osVersion); if (configFile != null) { return configFile; } } if (osName != null) { configFile = findImpl(baseName + "." + osName); if (configFile != null) { return configFile; } } if (osVersion != null) { configFile = findImpl(baseName + "." + osVersion); if (configFile != null) { return configFile; } } foundOsSpecificFile = false; configFile = findImpl(baseName); if (configFile != null) { return configFile; } return null; } /* Initialize the internal data tables from binary format font * configuration file. */ public static void loadBinary(InputStream inStream) throws IOException { DataInputStream in = new DataInputStream(inStream); head = readShortTable(in, HEAD_LENGTH); int[] tableSizes = new int[INDEX_TABLEEND]; for (int i = 0; i < INDEX_TABLEEND; i++) { tableSizes[i] = head[i + 1] - head[i]; } table_scriptIDs = readShortTable(in, tableSizes[INDEX_scriptIDs]); table_scriptFonts = readShortTable(in, tableSizes[INDEX_scriptFonts]); table_elcIDs = readShortTable(in, tableSizes[INDEX_elcIDs]); table_sequences = readShortTable(in, tableSizes[INDEX_sequences]); table_fontfileNameIDs = readShortTable(in, tableSizes[INDEX_fontfileNameIDs]); table_componentFontNameIDs = readShortTable(in, tableSizes[INDEX_componentFontNameIDs]); table_filenames = readShortTable(in, tableSizes[INDEX_filenames]); table_awtfontpaths = readShortTable(in, tableSizes[INDEX_awtfontpaths]); table_exclusions = readShortTable(in, tableSizes[INDEX_exclusions]); table_proportionals = readShortTable(in, tableSizes[INDEX_proportionals]); table_scriptFontsMotif = readShortTable(in, tableSizes[INDEX_scriptFontsMotif]); table_alphabeticSuffix = readShortTable(in, tableSizes[INDEX_alphabeticSuffix]); table_stringIDs = readShortTable(in, tableSizes[INDEX_stringIDs]); //StringTable cache stringCache = new String[table_stringIDs.length + 1]; int len = tableSizes[INDEX_stringTable]; byte[] bb = new byte[len * 2]; table_stringTable = new char[len]; in.read(bb); int i = 0, j = 0; while (i < len) { table_stringTable[i++] = (char)(bb[j++] << 8 | (bb[j++] & 0xff)); } if (verbose) { dump(); } } /* Generate a binary format font configuration from internal data * tables. */ public static void saveBinary(OutputStream out) throws IOException { sanityCheck(); DataOutputStream dataOut = new DataOutputStream(out); writeShortTable(dataOut, head); writeShortTable(dataOut, table_scriptIDs); writeShortTable(dataOut, table_scriptFonts); writeShortTable(dataOut, table_elcIDs); writeShortTable(dataOut, table_sequences); writeShortTable(dataOut, table_fontfileNameIDs); writeShortTable(dataOut, table_componentFontNameIDs); writeShortTable(dataOut, table_filenames); writeShortTable(dataOut, table_awtfontpaths); writeShortTable(dataOut, table_exclusions); writeShortTable(dataOut, table_proportionals); writeShortTable(dataOut, table_scriptFontsMotif); writeShortTable(dataOut, table_alphabeticSuffix); writeShortTable(dataOut, table_stringIDs); //stringTable dataOut.writeChars(new String(table_stringTable)); out.close(); if (verbose) { dump(); } } //private static boolean loadingProperties; private static short stringIDNum; private static short[] stringIDs; private static StringBuilder stringTable; public static void loadProperties(InputStream in) throws IOException { //loadingProperties = true; //StringID starts from "1", "0" is reserved for "not defined" stringIDNum = 1; stringIDs = new short[1000]; stringTable = new StringBuilder(4096); if (verbose && logger == null) { logger = PlatformLogger.getLogger("sun.awt.FontConfiguration"); } new PropertiesHandler().load(in); //loadingProperties = false; stringIDs = null; stringTable = null; } ///////////////////////////////////////////////////////////////////// // methods for initializing the FontConfig // ///////////////////////////////////////////////////////////////////// /** * set initLocale, initEncoding and initELC for this FontConfig object * currently we just simply use the startup locale and encoding */ private void initFontConfig() { initLocale = startupLocale; initEncoding = encoding; if (preferLocaleFonts && !willReorderForStartupLocale()) { preferLocaleFonts = false; } initELC = getInitELC(); initAllComponentFonts(); } //"ELC" stands for "Encoding.Language.Country". This method returns //the ID of the matched elc setting of "initLocale" in elcIDs table. //If no match is found, it returns the default ID, which is //"NULL.NULL.NULL" in elcIDs table. private short getInitELC() { if (initELC != -1) { return initELC; } HashMap <String, Integer> elcIDs = new HashMap<String, Integer>(); for (int i = 0; i < table_elcIDs.length; i++) { elcIDs.put(getString(table_elcIDs[i]), i); } String language = initLocale.getLanguage(); String country = initLocale.getCountry(); String elc; if (elcIDs.containsKey(elc=initEncoding + "." + language + "." + country) || elcIDs.containsKey(elc=initEncoding + "." + language) || elcIDs.containsKey(elc=initEncoding)) { initELC = elcIDs.get(elc).shortValue(); } else { initELC = elcIDs.get("NULL.NULL.NULL").shortValue(); } int i = 0; while (i < table_alphabeticSuffix.length) { if (initELC == table_alphabeticSuffix[i]) { alphabeticSuffix = getString(table_alphabeticSuffix[i + 1]); return initELC; } i += 2; } return initELC; } public static boolean verbose; private short initELC = -1; private Locale initLocale; private String initEncoding; private String alphabeticSuffix; private short[][][] compFontNameIDs = new short[NUM_FONTS][NUM_STYLES][]; private int[][][] compExclusions = new int[NUM_FONTS][][]; private int[] compCoreNum = new int[NUM_FONTS]; private Set<Short> coreFontNameIDs = new HashSet<Short>(); private Set<Short> fallbackFontNameIDs = new HashSet<Short>(); private void initAllComponentFonts() { short[] fallbackScripts = getFallbackScripts(); for (int fontIndex = 0; fontIndex < NUM_FONTS; fontIndex++) { short[] coreScripts = getCoreScripts(fontIndex); compCoreNum[fontIndex] = coreScripts.length; /* System.out.println("coreScriptID=" + table_sequences[initELC * 5 + fontIndex]); for (int i = 0; i < coreScripts.length; i++) { System.out.println(" " + i + " :" + getString(table_scriptIDs[coreScripts[i]])); } */ //init exclusionRanges int[][] exclusions = new int[coreScripts.length][]; for (int i = 0; i < coreScripts.length; i++) { exclusions[i] = getExclusionRanges(coreScripts[i]); } compExclusions[fontIndex] = exclusions; //init componentFontNames for (int styleIndex = 0; styleIndex < NUM_STYLES; styleIndex++) { int index; short[] nameIDs = new short[coreScripts.length + fallbackScripts.length]; //core for (index = 0; index < coreScripts.length; index++) { nameIDs[index] = getComponentFontID(coreScripts[index], fontIndex, styleIndex); if (preferLocaleFonts && localeMap != null && fontManager.usingAlternateFontforJALocales()) { nameIDs[index] = remapLocaleMap(fontIndex, styleIndex, coreScripts[index], nameIDs[index]); } if (preferPropFonts) { nameIDs[index] = remapProportional(fontIndex, nameIDs[index]); } //System.out.println("nameid=" + nameIDs[index]); coreFontNameIDs.add(nameIDs[index]); } //fallback for (int i = 0; i < fallbackScripts.length; i++) { short id = getComponentFontID(fallbackScripts[i], fontIndex, styleIndex); if (preferLocaleFonts && localeMap != null && fontManager.usingAlternateFontforJALocales()) { id = remapLocaleMap(fontIndex, styleIndex, fallbackScripts[i], id); } if (preferPropFonts) { id = remapProportional(fontIndex, id); } if (contains(nameIDs, id, index)) { continue;