2272 lines · 92.3 KB · Java
RawDownload
/* * 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.