/*
 * Copyright 2000-2005 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.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.FileOutputStream;
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.logging.Logger;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
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.java2d.SunGraphicsEnvironment;

/**
 * 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 Logger logger;
    protected static boolean isProperties = true;

    protected SunGraphicsEnvironment environment;
    protected boolean preferLocaleFonts;
    protected boolean preferPropFonts;

    /* A default FontConfiguration must be created before an alternate
     * one to ensure proper static initialisation takes place.
     */
    public FontConfiguration(SunGraphicsEnvironment environment) {
        if (SunGraphicsEnvironment.debugFonts && logger == null) {
            logger = Logger.getLogger("sun.awt.FontConfiguration");
        }
        this.environment = environment;
        this.preferLocaleFonts = false;
        this.preferPropFonts = false;
        setOsNameAndVersion();  /* static initialization */
        setEncoding();          /* static initialization */
        fontConfig = this;      /* static initialization */

        readFontConfigFile();
        initFontConfig();
    }

    public FontConfiguration(SunGraphicsEnvironment environment,
                             boolean preferLocaleFonts,
                             boolean preferPropFonts) {
        this.environment = environment;
        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                         //
    /////////////////////////////////////////////////////////////////////
    private void readFontConfigFile() {
        // Find fontconfig file
        File f = null;
        String javaHome = System.getProperty("java.home");
        if (javaHome == null) {
            throw new Error("java.home property not set");
        }
        String javaLib = javaHome + File.separator + "lib";
        String userConfigFile = System.getProperty("sun.awt.fontconfig");
        if (userConfigFile != null) {
            f = new File(userConfigFile);
        } else {
            f = findFontConfigFile(javaLib);
        }

        /* 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 (SunGraphicsEnvironment.debugFonts) {
                    logger.config("Read logical font configuration from " + f);
                }
            } catch (IOException e) {
                if (SunGraphicsEnvironment.debugFonts) {
                    logger.config("Failed to read logical font configuration from " + f);
                }
            }
        }
        String version = getVersion();
        if (!"1".equals(version) && SunGraphicsEnvironment.debugFonts) {
            logger.config("Unsupported fontconfig version: " + version);
        }
    }

    private 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(SunGraphicsEnvironment.ttFilter);
            String[] t1s = fallbackDir.list(SunGraphicsEnvironment.t1Filter);
            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];
            }
            environment.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;
            }
        }
        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 {
        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();
        }
        sanityCheck();
    }

    //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 = Logger.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 &&
                        sun.font.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 &&
                        sun.font.FontManager.usingAlternateFontforJALocales()) {
                        id = remapLocaleMap(fontIndex, styleIndex, fallbackScripts[i], id);
                    }
                    if (preferPropFonts) {
                        id = remapProportional(fontIndex, id);
                    }
                    if (contains(nameIDs, id, index)) {
                        continue;
                    }
                    /*
                      System.out.println("fontIndex=" + fontIndex + ", styleIndex=" + styleIndex
                           + ", fbIndex=" + i + ",fbS=" + fallbackScripts[i] + ", id=" + id);
                    */
                    fallbackFontNameIDs.add(id);
                    nameIDs[index++] = id;
                }
                if (index < nameIDs.length) {
                    short[] newNameIDs = new short[index];
                    System.arraycopy(nameIDs, 0, newNameIDs, 0, index);
                    nameIDs = newNameIDs;
                }
                compFontNameIDs[fontIndex][styleIndex] = nameIDs;
            }
        }
   }

   private short remapLocaleMap(int fontIndex, int styleIndex, short scriptID, short fontID) {
        String scriptName = getString(table_scriptIDs[scriptID]);

        String value = (String)localeMap.get(scriptName);
        if (value == null) {
            String fontName = fontNames[fontIndex];
            String styleName = styleNames[styleIndex];
            value = (String)localeMap.get(fontName + "." + styleName + "." + scriptName);
        }
        if (value == null) {
            return fontID;
        }

        for (int i = 0; i < table_componentFontNameIDs.length; i++) {
            String name = getString(table_componentFontNameIDs[i]);
            if (value.equalsIgnoreCase(name)) {
                fontID = (short)i;
                break;
            }
        }
        return fontID;
    }

    public static boolean hasMonoToPropMap() {
        return table_proportionals != null && table_proportionals.length != 0;
    }

    private short remapProportional(int fontIndex, short id) {
    if (preferPropFonts &&
        table_proportionals.length != 0 &&
        fontIndex != 2 &&         //"monospaced"
        fontIndex != 4) {         //"dialoginput"
            int i = 0;
            while (i < table_proportionals.length) {
                if (table_proportionals[i] == id) {
                    return table_proportionals[i + 1];
                }
                i += 2;
            }
        }
        return id;
    }

    /////////////////////////////////////////////////////////////////////
    // Methods for handling font and style names                       //
    /////////////////////////////////////////////////////////////////////
    protected static final int NUM_FONTS = 5;
    protected static final int NUM_STYLES = 4;
    private static final String[] fontNames
            = {"serif", "sansserif", "monospaced", "dialog", "dialoginput"};
    private static final String[] publicFontNames
            = {Font.SERIF, Font.SANS_SERIF, Font.MONOSPACED, Font.DIALOG,
               Font.DIALOG_INPUT};
    private static final String[] styleNames
            = {"plain", "bold", "italic", "bolditalic"};

    /**
     * Checks whether the given font family name is a valid logical font name.
     * The check is case insensitive.
     */
    public static boolean isLogicalFontFamilyName(String fontName) {
        return isLogicalFontFamilyNameLC(fontName.toLowerCase(Locale.ENGLISH));
    }

    /**
     * Checks whether the given font family name is a valid logical font name.
     * The check is case sensitive.
     */
    public static boolean isLogicalFontFamilyNameLC(String fontName) {
        for (int i = 0; i < fontNames.length; i++) {
            if (fontName.equals(fontNames[i])) {
                return true;
            }
        }
        return false;
    }

    /**
     * Checks whether the given style name is a valid logical font style name.
     */
    private static boolean isLogicalFontStyleName(String styleName) {
        for (int i = 0; i < styleNames.length; i++) {
            if (styleName.equals(styleNames[i])) {
                return true;
            }
        }
        return false;
    }

    /**
     * Checks whether the given font face name is a valid logical font name.
     * The check is case insensitive.
     */
    public static boolean isLogicalFontFaceName(String fontName) {
        return isLogicalFontFaceNameLC(fontName.toLowerCase(Locale.ENGLISH));
    }

   /**
    * Checks whether the given font face name is a valid logical font name.
    * The check is case sensitive.
    */
    public static boolean isLogicalFontFaceNameLC(String fontName) {
        int period = fontName.indexOf('.');
        if (period >= 0) {
            String familyName = fontName.substring(0, period);
            String styleName = fontName.substring(period + 1);
            return isLogicalFontFamilyName(familyName) &&
                    isLogicalFontStyleName(styleName);
        } else {
            return isLogicalFontFamilyName(fontName);
        }
    }

    protected static int getFontIndex(String fontName) {
        return getArrayIndex(fontNames, fontName);
    }

    protected static int getStyleIndex(String styleName) {
        return getArrayIndex(styleNames, styleName);
    }

    private static int getArrayIndex(String[] names, String name) {
        for (int i = 0; i < names.length; i++) {
            if (name.equals(names[i])) {
                return i;
            }
        }
        assert false;
        return 0;
    }

    protected static int getStyleIndex(int style) {
        switch (style) {
            case Font.PLAIN:
                return 0;
            case Font.BOLD:
                return 1;
            case Font.ITALIC:
                return 2;
            case Font.BOLD | Font.ITALIC:
                return 3;
            default:
                return 0;
        }
    }

    protected static String getFontName(int fontIndex) {
        return fontNames[fontIndex];
    }

    protected static String getStyleName(int styleIndex) {
        return styleNames[styleIndex];
    }

    /**
     * Returns the font face name for the given logical font
     * family name and style.
     * The style argument is interpreted as in java.awt.Font.Font.
     */
    public static String getLogicalFontFaceName(String familyName, int style) {
        assert isLogicalFontFamilyName(familyName);
        return familyName.toLowerCase(Locale.ENGLISH) + "." + getStyleString(style);
    }

    /**
     * Returns the string typically used in properties files
     * for the given style.
     * The style argument is interpreted as in java.awt.Font.Font.
     */
    public static String getStyleString(int style) {
        return getStyleName(getStyleIndex(style));
    }

    /**
     * Returns a fallback name for the given font name. For a few known
     * font names, matching logical font names are returned. For all
     * other font names, defaultFallback is returned.
     * defaultFallback differs between AWT and 2D.
     */
    public abstract String getFallbackFamilyName(String fontName, String defaultFallback);

    /**
     * Returns the 1.1 equivalent for some old 1.0 font family names for
     * which we need to maintain compatibility in some configurations.
     * Returns null for other font names.
     */
    protected String getCompatibilityFamilyName(String fontName) {
        fontName = fontName.toLowerCase(Locale.ENGLISH);
        if (fontName.equals("timesroman")) {
            return "serif";
        } else if (fontName.equals("helvetica")) {
            return "sansserif";
        } else if (fontName.equals("courier")) {
            return "monospaced";
        }
        return null;
    }

    private static String[] installedFallbackFontFiles = null;

    /**
     * Maps a file name given in the font configuration file
     * to a format appropriate for the platform.
     */
    protected String mapFileName(String fileName) {
        return fileName;
    }

    //////////////////////////////////////////////////////////////////////
    //  reordering                                                      //
    //////////////////////////////////////////////////////////////////////

    /* Mappings from file encoding to font config name for font supporting
     * the corresponding language. This is filled in by initReorderMap()
     */
    protected HashMap reorderMap = null;

    /* Platform-specific mappings */
    protected abstract void initReorderMap();

    /* Move item at index "src" to "dst", shuffling all values in
     * between down
     */
    private void shuffle(String[] seq, int src, int dst) {
        if (dst >= src) {
            return;
        }
        String tmp = seq[src];
        for (int i=src; i>dst; i--) {
            seq[i] = seq[i-1];
        }
        seq[dst] = tmp;
    }

    /* Called to determine if there's a re-order sequence for this locale/
     * encoding. If there's none then the caller can "bail" and avoid
     * unnecessary work
     */
    public static boolean willReorderForStartupLocale() {
        return getReorderSequence() != null;
    }

    private static Object getReorderSequence() {
        if (fontConfig.reorderMap == null) {
             fontConfig.initReorderMap();
        }
        HashMap reorderMap = fontConfig.reorderMap;

        /* Find the most specific mapping */
        String language = startupLocale.getLanguage();
        String country = startupLocale.getCountry();
        Object val = reorderMap.get(encoding + "." + language + "." + country);
        if (val == null) {
            val = reorderMap.get(encoding + "." + language);
        }
        if (val == null) {
            val = reorderMap.get(encoding);
        }
        return val;
    }

    /* This method reorders the sequence such that the matches for the
     * file encoding are moved ahead of other elements.
     * If an encoding uses more than one font, they are all moved up.
     */
     private void reorderSequenceForLocale(String[] seq) {
        Object val =  getReorderSequence();
        if (val instanceof String) {
            for (int i=0; i< seq.length; i++) {
                if (seq[i].equals(val)) {
                    shuffle(seq, i, 0);
                    return;
                }
            }
        } else if (val instanceof String[]) {
            String[] fontLangs = (String[])val;
            for (int l=0; l<fontLangs.length;l++) {
                for (int i=0; i<seq.length;i++) {
                    if (seq[i].equals(fontLangs[l])) {
                        shuffle(seq, i, l);
                    }
                }
            }
        }
    }

    private static Vector splitSequence(String sequence) {
        //String.split would be more convenient, but incurs big performance penalty
        Vector parts = new Vector();
        int start = 0;
        int end;
        while ((end = sequence.indexOf(',', start)) >= 0) {
            parts.add(sequence.substring(start, end));
            start = end + 1;
        }
        if (sequence.length() > start) {
            parts.add(sequence.substring(start, sequence.length()));
        }
        return parts;
    }

    protected String[] split(String sequence) {
        Vector v = splitSequence(sequence);
        return (String[])v.toArray(new String[0]);
    }

    ////////////////////////////////////////////////////////////////////////
    // Methods for extracting information from the fontconfig data for AWT//
    ////////////////////////////////////////////////////////////////////////
    private Hashtable charsetRegistry = new Hashtable(5);

    /**
     * Returns FontDescriptors describing the physical fonts used for the
     * given logical font name and style. The font name is interpreted
     * in a case insensitive way.
     * The style argument is interpreted as in java.awt.Font.Font.
     */
    public FontDescriptor[] getFontDescriptors(String fontName, int style) {
        assert isLogicalFontFamilyName(fontName);
        fontName = fontName.toLowerCase(Locale.ENGLISH);
        int fontIndex = getFontIndex(fontName);
        int styleIndex = getStyleIndex(style);
        return getFontDescriptors(fontIndex, styleIndex);
    }
    private FontDescriptor[][][] fontDescriptors =
        new FontDescriptor[NUM_FONTS][NUM_STYLES][];

    private FontDescriptor[] getFontDescriptors(int fontIndex, int styleIndex) {
        FontDescriptor[] descriptors = fontDescriptors[fontIndex][styleIndex];
        if (descriptors == null) {
            descriptors = buildFontDescriptors(fontIndex, styleIndex);
            fontDescriptors[fontIndex][styleIndex] = descriptors;
        }
        return descriptors;
    }

    private FontDescriptor[] buildFontDescriptors(int fontIndex, int styleIndex) {
        String fontName = fontNames[fontIndex];
        String styleName = styleNames[styleIndex];

        short[] scriptIDs = getCoreScripts(fontIndex);
        short[] nameIDs = compFontNameIDs[fontIndex][styleIndex];
        String[] sequence = new String[scriptIDs.length];
        String[] names = new String[scriptIDs.length];
        for (int i = 0; i < sequence.length; i++) {
            names[i] = getComponentFontName(nameIDs[i]);
            sequence[i] = getScriptName(scriptIDs[i]);
            if (alphabeticSuffix != null && "alphabetic".equals(sequence[i])) {
                sequence[i] = sequence[i] + "/" + alphabeticSuffix;
            }
        }
        int[][] fontExclusionRanges = compExclusions[fontIndex];

        FontDescriptor[] descriptors = new FontDescriptor[names.length];

        for (int i = 0; i < names.length; i++) {
            String awtFontName;
            String encoding;

            awtFontName = makeAWTFontName(names[i], sequence[i]);

            // look up character encoding
            encoding = getEncoding(names[i], sequence[i]);
            if (encoding == null) {
                encoding = "default";
            }
            CharsetEncoder enc
                    = getFontCharsetEncoder(encoding.trim(), awtFontName);

            // we already have the exclusion ranges
            int[] exclusionRanges = fontExclusionRanges[i];

            // create descriptor
            descriptors[i] = new FontDescriptor(awtFontName, enc, exclusionRanges);
        }
        return descriptors;
    }

    /**
     * Returns the AWT font name for the given platform font name and
     * character subset.
     */
    protected String makeAWTFontName(String platformFontName,
            String characterSubsetName) {
        return platformFontName;
    }

    /**
     * Returns the java.io name of the platform character encoding for the
     * given AWT font name and character subset. May return "default"
     * to indicate that getDefaultFontCharset should be called to obtain
     * a charset encoder.
     */
    protected abstract String getEncoding(String awtFontName,
            String characterSubsetName);

    private CharsetEncoder getFontCharsetEncoder(final String charsetName,
            String fontName) {

        Charset fc = null;
        if (charsetName.equals("default")) {
            fc = (Charset) charsetRegistry.get(fontName);
        } else {
            fc = (Charset) charsetRegistry.get(charsetName);
        }
        if (fc != null) {
            return fc.newEncoder();
        }

        if (!charsetName.startsWith("sun.awt.") && !charsetName.equals("default")) {
            fc = Charset.forName(charsetName);
        } else {
            Class fcc = (Class) AccessController.doPrivileged(new PrivilegedAction() {
                    public Object run() {
                        try {
                            return Class.forName(charsetName, true,
                                                 Thread.currentThread().getContextClassLoader());
                        } catch (ClassNotFoundException e) {
                        }
                        return null;
                    }
                });

            if (fcc != null) {
                try {
                    fc = (Charset) fcc.newInstance();
                } catch (Exception e) {
                }
            }
        }
        if (fc == null) {
            fc = getDefaultFontCharset(fontName);
        }

        if (charsetName.equals("default")){
            charsetRegistry.put(fontName, fc);
        } else {
            charsetRegistry.put(charsetName, fc);
        }
        return fc.newEncoder();
    }

    protected abstract Charset getDefaultFontCharset(
            String fontName);

    /* This retrieves the platform font directories (path) calculated
     * by setAWTFontPathSequence(String[]). The default implementation
     * returns null, its expected that X11 platforms may return
     * non-null.
     */
    public HashSet<String> getAWTFontPathSet() {
        return null;
    }

    ////////////////////////////////////////////////////////////////////////
    // methods for extracting information from the fontconfig data for 2D //
    ////////////////////////////////////////////////////////////////////////

    /**
     * Returns an array of composite font descriptors for all logical font
     * faces.
     * If the font configuration file doesn't specify Lucida Sans Regular
     * or the given fallback font as component fonts, they are added here.
     */
    public CompositeFontDescriptor[] get2DCompositeFontInfo() {
        CompositeFontDescriptor[] result =
                new CompositeFontDescriptor[NUM_FONTS * NUM_STYLES];
        String defaultFontFile = environment.getDefaultFontFile();
        String defaultFontFaceName = environment.getDefaultFontFaceName();

        for (int fontIndex = 0; fontIndex < NUM_FONTS; fontIndex++) {
            String fontName = publicFontNames[fontIndex];

            // determine exclusion ranges for font
            // AWT uses separate exclusion range array per component font.
            // 2D packs all range boundaries into one array.
            // Both use separate entries for lower and upper boundary.
            int[][] exclusions = compExclusions[fontIndex];
            int numExclusionRanges = 0;
            for (int i = 0; i < exclusions.length; i++) {
                numExclusionRanges += exclusions[i].length;
            }
            int[] exclusionRanges = new int[numExclusionRanges];
            int[] exclusionRangeLimits = new int[exclusions.length];
            int exclusionRangeIndex = 0;
            int exclusionRangeLimitIndex = 0;
            for (int i = 0; i < exclusions.length; i++) {
                int[] componentRanges = exclusions[i];
                for (int j = 0; j < componentRanges.length; ) {
                    int value = componentRanges[j];
                    exclusionRanges[exclusionRangeIndex++] = componentRanges[j++];
                    exclusionRanges[exclusionRangeIndex++] = componentRanges[j++];
                }
                exclusionRangeLimits[i] = exclusionRangeIndex;
            }
            // other info is per style
            for (int styleIndex = 0; styleIndex < NUM_STYLES; styleIndex++) {
                int maxComponentFontCount = compFontNameIDs[fontIndex][styleIndex].length;
                boolean sawDefaultFontFile = false;
                // fall back fonts listed in the lib/fonts/fallback directory
                if (installedFallbackFontFiles != null) {
                    maxComponentFontCount += installedFallbackFontFiles.length;
                }
                String faceName = fontName + "." + styleNames[styleIndex];

                // determine face names and file names of component fonts
                String[] componentFaceNames = new String[maxComponentFontCount];
                String[] componentFileNames = new String[maxComponentFontCount];

                int index;
                for (index = 0; index < compFontNameIDs[fontIndex][styleIndex].length; index++) {
                    short fontNameID = compFontNameIDs[fontIndex][styleIndex][index];
                    short fileNameID = getComponentFileID(fontNameID);
                    componentFaceNames[index] = getFaceNameFromComponentFontName(getComponentFontName(fontNameID));
                    componentFileNames[index] = mapFileName(getComponentFileName(fileNameID));
                    if (componentFileNames[index] == null ||
                        needToSearchForFile(componentFileNames[index])) {
                        componentFileNames[index] = getFileNameFromComponentFontName(getComponentFontName(fontNameID));
                    }
                    if (!sawDefaultFontFile &&
                        defaultFontFile.equals(componentFileNames[index])) {
                        sawDefaultFontFile = true;
                    }
                    /*
                    System.out.println(publicFontNames[fontIndex] + "." + styleNames[styleIndex] + "."
                        + getString(table_scriptIDs[coreScripts[index]]) + "=" + componentFileNames[index]);
                    */
                }

                //"Lucida Sans Regular" is not in the list, we add it here
                if (!sawDefaultFontFile) {
                    int len = 0;
                    if (installedFallbackFontFiles != null) {
                        len = installedFallbackFontFiles.length;
                    }
                    if (index + len == maxComponentFontCount) {
                        String[] newComponentFaceNames = new String[maxComponentFontCount + 1];
                        System.arraycopy(componentFaceNames, 0, newComponentFaceNames, 0, index);
                        componentFaceNames = newComponentFaceNames;
                        String[] newComponentFileNames = new String[maxComponentFontCount + 1];
                        System.arraycopy(componentFileNames, 0, newComponentFileNames, 0, index);
                        componentFileNames = newComponentFileNames;
                    }
                    componentFaceNames[index] = defaultFontFaceName;
                    componentFileNames[index] = defaultFontFile;
                    index++;
                }

                if (installedFallbackFontFiles != null) {
                    for (int ifb=0; ifb<installedFallbackFontFiles.length; ifb++) {
                        componentFaceNames[index] = null;
                        componentFileNames[index] = installedFallbackFontFiles[ifb];
                        index++;
                    }
                }

                if (index < maxComponentFontCount) {
                    String[] newComponentFaceNames = new String[index];
                    System.arraycopy(componentFaceNames, 0, newComponentFaceNames, 0, index);
                    componentFaceNames = newComponentFaceNames;
                    String[] newComponentFileNames = new String[index];
                    System.arraycopy(componentFileNames, 0, newComponentFileNames, 0, index);
                    componentFileNames = newComponentFileNames;
                }
                // exclusion range limit array length must match component face name
                // array length - native code relies on this

                int[] clippedExclusionRangeLimits = exclusionRangeLimits;
                if (index != clippedExclusionRangeLimits.length) {
                    int len = exclusionRangeLimits.length;
                    clippedExclusionRangeLimits = new int[index];
                    System.arraycopy(exclusionRangeLimits, 0, clippedExclusionRangeLimits, 0, len);
                    //padding for various fallback fonts
                    for (int i = len; i < index; i++) {
                        clippedExclusionRangeLimits[i] = exclusionRanges.length;
                    }
                }
                /*
                System.out.println(faceName + ":");
                for (int i = 0; i < componentFileNames.length; i++) {
                    System.out.println("    " + componentFaceNames[i]
                         + "  -> " + componentFileNames[i]);
                }
                */
                result[fontIndex * NUM_STYLES + styleIndex]
                        = new CompositeFontDescriptor(
                            faceName,
                            compCoreNum[fontIndex],
                            componentFaceNames,
                            componentFileNames,
                            exclusionRanges,
                            clippedExclusionRangeLimits);
            }
        }
        return result;
    }

    protected abstract String getFaceNameFromComponentFontName(String componentFontName);
    protected abstract String getFileNameFromComponentFontName(String componentFontName);

    /*
    public class 2dFont {
        public String platformName;
        public String fontfileName;
    }
    private 2dFont [] componentFonts = null;
    */

    /* Used on Linux to test if a file referenced in a font configuration
     * file exists in the location that is expected. If it does, no need
     * to search for it. If it doesn't then unless its a fallback font,
     * return that expensive code should be invoked to search for the font.
     */
    HashMap<String, Boolean> existsMap;
    public boolean needToSearchForFile(String fileName) {
        if (!environment.isLinux) {
            return false;
        } else if (existsMap == null) {
           existsMap = new HashMap<String, Boolean>();
        }
        Boolean exists = existsMap.get(fileName);
        if (exists == null) {
            /* call getNumberCoreFonts() to ensure these are initialised, and
             * if this file isn't for a core component, ie, is a for a fallback
             * font which very typically isn't available, then can't afford
             * to take the start-up penalty to search for it.
             */
            getNumberCoreFonts();
            if (!coreFontFileNames.contains(fileName)) {
                exists = Boolean.TRUE;
            } else {
                exists = Boolean.valueOf((new File(fileName)).exists());
                existsMap.put(fileName, exists);
                if (SunGraphicsEnvironment.debugFonts &&
                    exists == Boolean.FALSE) {
                    logger.warning("Couldn't locate font file " + fileName);
                }
            }
        }
        return exists == Boolean.FALSE;
    }

    private int numCoreFonts = -1;
    private String[] componentFonts = null;
    HashMap <String, String> filenamesMap = new HashMap<String, String>();
    HashSet <String> coreFontFileNames = new HashSet<String>();

    /* Return the number of core fonts. Note this isn't thread safe but
     * a calling thread can call this and getPlatformFontNames() in either
     * order.
     */
    public int getNumberCoreFonts() {
        if (numCoreFonts == -1) {
            numCoreFonts = coreFontNameIDs.size();
            Short[] emptyShortArray = new Short[0];
            Short[] core = coreFontNameIDs.toArray(emptyShortArray);
            Short[] fallback = fallbackFontNameIDs.toArray(emptyShortArray);

            int numFallbackFonts = 0;
            int i;
            for (i = 0; i < fallback.length; i++) {
                if (coreFontNameIDs.contains(fallback[i])) {
                    fallback[i] = null;
                    continue;
                }
                numFallbackFonts++;
            }
            componentFonts = new String[numCoreFonts + numFallbackFonts];
            String filename = null;
            for (i = 0; i < core.length; i++) {
                short fontid = core[i];
                short fileid = getComponentFileID(fontid);
                componentFonts[i] = getComponentFontName(fontid);
                String compFileName = getComponentFileName(fileid);
                if (compFileName != null) {
                    coreFontFileNames.add(compFileName);
                }
                filenamesMap.put(componentFonts[i], mapFileName(compFileName));
            }
            for (int j = 0; j < fallback.length; j++) {
                if (fallback[j] != null) {
                    short fontid = fallback[j];
                    short fileid = getComponentFileID(fontid);
                    componentFonts[i] = getComponentFontName(fontid);
                    filenamesMap.put(componentFonts[i],
                                     mapFileName(getComponentFileName(fileid)));
                    i++;
                }
            }
        }
        return numCoreFonts;
    }

    /* Return all platform font names used by this font configuration.
     * The first getNumberCoreFonts() entries are guaranteed to be the
     * core fonts - ie no fall back only fonts.
     */
    public String[] getPlatformFontNames() {
        if (numCoreFonts == -1) {
            getNumberCoreFonts();
        }
        return componentFonts;
    }

    /**
     * Returns a file name for the physical font represented by this platform font name,
     * if the font configuration has such information available, or null if the
     * information is unavailable. The file name returned is just a hint; a null return
     * value doesn't necessarily mean that the font is unavailable, nor does a non-null
     * return value guarantee that the file exists and contains the physical font.
     * The file name can be an absolute or a relative path name.
     */
    public String getFileNameFromPlatformName(String platformName) {
        // get2DCompositeFontInfo
        //     ->  getFileNameFromComponentfontName()  (W/M)
        //       ->   getFileNameFromPlatformName()
        // it's a waste of time on Win32, but I have to give X11 a chance to
        // call getFileNameFromXLFD()
        return filenamesMap.get(platformName);
    }

    /**
     * Returns a configuration specific path to be appended to the font
     * search path.
     */
    public String getExtraFontPath() {
        return getString(head[INDEX_appendedfontpath]);
    }

    public String getVersion() {
        return getString(head[INDEX_version]);
    }

    /* subclass support */
    protected static FontConfiguration getFontConfiguration() {
        return fontConfig;
    }

    //////////////////////////////////////////////////////////////////////
    // FontConfig data tables and the index constants in binary file    //
    //////////////////////////////////////////////////////////////////////
    /* The binary font configuration file begins with a short[] "head", which
     * contains the offsets to the starts of the individual data table which
     * immediately follow. Teh current implemention includes the tables shown
     * below.
     *
     * (00) table_scriptIDs    :stringIDs of all defined CharacterSubsetNames
     * (01) table_scriptFonts  :scriptID x fontIndex x styleIndex->
     *                          PlatformFontNameID mapping. Each scriptID might
     *                          have 1 or 20 entries depends on if it is defined
     *                          via a "allfonts.CharacterSubsetname" or a list of
     *                          "LogicalFontName.StyleName.CharacterSubsetName"
     *                          entries, positive entry means it's a "allfonts"
     *                          entry, a negative value means this is a offset to
     *                          a NUM_FONTS x NUM_STYLES subtable.
     * (02) table_elcIDs       :stringIDs of all defined ELC names, string
     *                          "NULL.NULL.NULL" is used for "default"
     * (03) table_sequences    :elcID x logicalFont -> scriptIDs table defined
     *                          by "sequence.allfonts/LogicalFontName.ELC" in
     *                          font configuration file, each "elcID" has
     *                          NUM_FONTS (5) entries in this table.
     * (04) table_fontfileNameIDs
     *                         :stringIDs of all defined font file names
     * (05) table_componentFontNameIDs
     *                         :stringIDs of all defined PlatformFontNames
     * (06) table_filenames    :platformFontNamesID->fontfileNameID mapping
     *                          table, the index is the platformFontNamesID.
     * (07) table_awtfontpaths :CharacterSubsetNames->awtfontpaths mapping table,
     *                          the index is the CharacterSubsetName's stringID
     *                          and content is the stringID of awtfontpath.
     * (08) table_exclusions   :scriptID -> exclusionRanges mapping table,
     *                          the index is the scriptID and the content is
                                a id of an exclusionRanges int[].
     * (09) table_proportionals:list of pairs of PlatformFontNameIDs, stores
     *                          the replacement info defined by "proportional"
     *                          keyword.
     * (10) table_scriptFontsMotif
     *                         :same as (01) except this table stores the
     *                          info defined with ".motif" keyword
     * (11) table_alphabeticSuffix
     *                         :elcID -> stringID of alphabetic/XXXX entries
     * (12) table_stringIDs    :The index of this table is the string ID, the
     *                          content is the "start index" of this string in
     *                          stringTable, use the start index of next entry
     *                          as the "end index".
     * (13) table_stringTable  :The real storage of all character strings defined
     *                          /used this font configuration, need a pair of
     *                          "start" and "end" indices to access.
     * (14) reserved
     * (15) table_fallbackScripts
     *                         :stringIDs of fallback CharacterSubsetnames, stored
     *                          in the order of they are defined in sequence.fallback.
     * (16) table_appendedfontpath
     *                         :stringtID of the "appendedfontpath" defined.
     * (17) table_version   :stringID of the version number of this fontconfig file.
     */
    private static final int HEAD_LENGTH = 20;
    private static final int INDEX_scriptIDs = 0;
    private static final int INDEX_scriptFonts = 1;
    private static final int INDEX_elcIDs = 2;
    private static final int INDEX_sequences = 3;
    private static final int INDEX_fontfileNameIDs = 4;
    private static final int INDEX_componentFontNameIDs = 5;
    private static final int INDEX_filenames = 6;
    private static final int INDEX_awtfontpaths = 7;
    private static final int INDEX_exclusions = 8;
    private static final int INDEX_proportionals = 9;
    private static final int INDEX_scriptFontsMotif = 10;
    private static final int INDEX_alphabeticSuffix = 11;
    private static final int INDEX_stringIDs = 12;
    private static final int INDEX_stringTable = 13;
    private static final int INDEX_TABLEEND = 14;
    private static final int INDEX_fallbackScripts = 15;
    private static final int INDEX_appendedfontpath = 16;
    private static final int INDEX_version = 17;

    private static short[] head;
    private static short[] table_scriptIDs;
    private static short[] table_scriptFonts;
    private static short[] table_elcIDs;
    private static short[] table_sequences;
    private static short[] table_fontfileNameIDs;
    private static short[] table_componentFontNameIDs;
    private static short[] table_filenames;
    protected static short[] table_awtfontpaths;
    private static short[] table_exclusions;
    private static short[] table_proportionals;
    private static short[] table_scriptFontsMotif;
    private static short[] table_alphabeticSuffix;
    private static short[] table_stringIDs;
    private static char[]  table_stringTable;

    private static void sanityCheck() {
        int errors = 0;

        //This method will only be called during build time, do we
        //need do PrivilegedAction?
        String osName = (String)java.security.AccessController.doPrivileged(
                            new java.security.PrivilegedAction() {
            public Object run() {
                return System.getProperty("os.name");
            }
        });

        //componentFontNameID starts from "1"
        for (int ii = 1; ii < table_filenames.length; ii++) {
            if (table_filenames[ii] == -1) {
                System.out.println("\n Warning: "
                                   + "<filename."
                                   + getString(table_componentFontNameIDs[ii])
                                   + "> entry is missing!!!");
                if (!osName.contains("Linux")) {
                    errors++;
                }
            }
        }
        for (int ii = 0; ii < table_scriptIDs.length; ii++) {
            short fid = table_scriptFonts[ii];
            if (fid == 0) {
                System.out.println("\n Error: <allfonts."
                                   + getString(table_scriptIDs[ii])
                                   + "> entry is missing!!!");
                errors++;
                continue;
            } else if (fid < 0) {
                fid = (short)-fid;
                for (int iii = 0; iii < NUM_FONTS; iii++) {
                    for (int iij = 0; iij < NUM_STYLES; iij++) {
                        int jj = iii * NUM_STYLES + iij;
                        short ffid = table_scriptFonts[fid + jj];
                        if (ffid == 0) {
                            System.out.println("\n Error: <"
                                           + getFontName(iii) + "."
                                           + getStyleName(iij) + "."
                                           + getString(table_scriptIDs[ii])
                                           + "> entry is missing!!!");
                            errors++;
                        }
                    }
                }
            }
        }
        if ("SunOS".equals(osName)) {
            for (int ii = 0; ii < table_awtfontpaths.length; ii++) {
                if (table_awtfontpaths[ii] == 0) {
                    String script = getString(table_scriptIDs[ii]);
                    if (script.contains("lucida") ||
                        script.contains("dingbats") ||
                        script.contains("symbol")) {
                        continue;
                    }
                    System.out.println("\nError: "
                                       + "<awtfontpath."
                                       + script
                                       + "> entry is missing!!!");
                    errors++;
                }
            }
        }
        if (errors != 0) {
            System.out.println("!!THERE ARE " + errors + " ERROR(S) IN "
                               + "THE FONTCONFIG FILE, PLEASE CHECK ITS CONTENT!!\n");
            System.exit(1);

        }
    }

    //dump the fontconfig data tables
    private static void dump() {
        System.out.println("\n----Head Table------------");
        for (int ii = 0; ii < HEAD_LENGTH; ii++) {
            System.out.println("  " + ii + " : " + head[ii]);
        }
        System.out.println("\n----scriptIDs-------------");
        printTable(table_scriptIDs, 0);
        System.out.println("\n----scriptFonts----------------");
        for (int ii = 0; ii < table_scriptIDs.length; ii++) {
            short fid = table_scriptFonts[ii];
            if (fid >= 0) {
                System.out.println("  allfonts."
                                   + getString(table_scriptIDs[ii])
                                   + "="
                                   + getString(table_componentFontNameIDs[fid]));
            }
        }
        for (int ii = 0; ii < table_scriptIDs.length; ii++) {
            short fid = table_scriptFonts[ii];
            if (fid < 0) {
                fid = (short)-fid;
                for (int iii = 0; iii < NUM_FONTS; iii++) {
                    for (int iij = 0; iij < NUM_STYLES; iij++) {
                        int jj = iii * NUM_STYLES + iij;
                        short ffid = table_scriptFonts[fid + jj];
                        System.out.println("  "
                                           + getFontName(iii) + "."
                                           + getStyleName(iij) + "."
                                           + getString(table_scriptIDs[ii])
                                           + "="
                                           + getString(table_componentFontNameIDs[ffid]));
                    }
                }

            }
        }
        System.out.println("\n----elcIDs----------------");
        printTable(table_elcIDs, 0);
        System.out.println("\n----sequences-------------");
        for (int ii = 0; ii< table_elcIDs.length; ii++) {
            System.out.println("  " + ii + "/" + getString((short)table_elcIDs[ii]));
            short[] ss = getShortArray(table_sequences[ii * NUM_FONTS + 0]);
            for (int jj = 0; jj < ss.length; jj++) {
                System.out.println("     " + getString((short)table_scriptIDs[ss[jj]]));
            }
        }
        System.out.println("\n----fontfileNameIDs-------");
        printTable(table_fontfileNameIDs, 0);

        System.out.println("\n----componentFontNameIDs--");
        printTable(table_componentFontNameIDs, 1);
        System.out.println("\n----filenames-------------");
        for (int ii = 0; ii < table_filenames.length; ii++) {
            if (table_filenames[ii] == -1) {
                System.out.println("  " + ii + " : null");
            } else {
                System.out.println("  " + ii + " : "
                   + getString(table_fontfileNameIDs[table_filenames[ii]]));
            }
        }
        System.out.println("\n----awtfontpaths---------");
        for (int ii = 0; ii < table_awtfontpaths.length; ii++) {
            System.out.println("  " + getString(table_scriptIDs[ii])
                               + " : "
                               + getString(table_awtfontpaths[ii]));
        }
        System.out.println("\n----proportionals--------");
        for (int ii = 0; ii < table_proportionals.length; ii++) {
            System.out.println("  "
                   + getString((short)table_componentFontNameIDs[table_proportionals[ii++]])
                   + " -> "
                   + getString((short)table_componentFontNameIDs[table_proportionals[ii]]));
        }
        int i = 0;
        System.out.println("\n----alphabeticSuffix----");
        while (i < table_alphabeticSuffix.length) {
          System.out.println("    " + getString(table_elcIDs[table_alphabeticSuffix[i++]])
                             + " -> " + getString(table_alphabeticSuffix[i++]));
        }
        System.out.println("\n----String Table---------");
        System.out.println("    stringID:    Num =" + table_stringIDs.length);
        System.out.println("    stringTable: Size=" + table_stringTable.length * 2);

        System.out.println("\n----fallbackScriptIDs---");
        short[] fbsIDs = getShortArray(head[INDEX_fallbackScripts]);
        for (int ii = 0; ii < fbsIDs.length; ii++) {
          System.out.println("  " + getString(table_scriptIDs[fbsIDs[ii]]));
        }
        System.out.println("\n----appendedfontpath-----");
        System.out.println("  " + getString(head[INDEX_appendedfontpath]));
        System.out.println("\n----Version--------------");
        System.out.println("  " + getString(head[INDEX_version]));
    }


    //////////////////////////////////////////////////////////////////////
    // Data table access methods                                        //
    //////////////////////////////////////////////////////////////////////

    /* Return the fontID of the platformFontName defined in this font config
     * by "LogicalFontName.StyleName.CharacterSubsetName" entry or
     * "allfonts.CharacterSubsetName" entry in properties format fc file.
     */
    protected static short getComponentFontID(short scriptID, int fontIndex, int styleIndex) {
        short fid = table_scriptFonts[scriptID];
        //System.out.println("fid=" + fid + "/ scriptID=" + scriptID + ", fi=" + fontIndex + ", si=" + styleIndex);
        if (fid >= 0) {
            //"allfonts"
            return fid;
        } else {
            return table_scriptFonts[-fid + fontIndex * NUM_STYLES + styleIndex];
        }
    }

    /* Same as getCompoentFontID() except this method returns the fontID define by
     * "xxxx.motif" entry.
     */
    protected static short getComponentFontIDMotif(short scriptID, int fontIndex, int styleIndex) {
        if (table_scriptFontsMotif.length == 0) {
            return 0;
        }
        short fid = table_scriptFontsMotif[scriptID];
        if (fid >= 0) {
            //"allfonts" > 0 or "not defined" == 0
            return fid;
        } else {
            return table_scriptFontsMotif[-fid + fontIndex * NUM_STYLES + styleIndex];
        }
    }

    private static int[] getExclusionRanges(short scriptID) {
        short exID = table_exclusions[scriptID];
        if (exID == 0) {
            return EMPTY_INT_ARRAY;
        } else {
            char[] exChar = getString(exID).toCharArray();
            int[] exInt = new int[exChar.length / 2];
            int i = 0;
            for (int j = 0; j < exInt.length; j++) {
                exInt[j] = (exChar[i++] << 16) + (exChar[i++] & 0xffff);
            }
            return exInt;
        }
    }

    private static boolean contains(short IDs[], short id, int limit) {
        for (int i = 0; i < limit; i++) {
            if (IDs[i] == id) {
                return true;
            }
        }
        return false;
    }

    /* Return the PlatformFontName from its fontID*/
    protected static String getComponentFontName(short id) {
        if (id < 0) {
            return null;
        }
        return getString(table_componentFontNameIDs[id]);
    }

    private static String getComponentFileName(short id) {
        if (id < 0) {
            return null;
        }
        return getString(table_fontfileNameIDs[id]);
    }

    //componentFontID -> componentFileID
    private static short getComponentFileID(short nameID) {
        return table_filenames[nameID];
    }

    private static String getScriptName(short scriptID) {
        return getString(table_scriptIDs[scriptID]);
    }

   private HashMap<String, Short> reorderScripts;
   protected short[] getCoreScripts(int fontIndex) {
        short elc = getInitELC();
        /*
          System.out.println("getCoreScripts: elc=" + elc + ", fontIndex=" + fontIndex);
          short[] ss = getShortArray(table_sequences[elc * NUM_FONTS + fontIndex]);
          for (int i = 0; i < ss.length; i++) {
              System.out.println("     " + getString((short)table_scriptIDs[ss[i]]));
          }
          */
        short[] scripts = getShortArray(table_sequences[elc * NUM_FONTS + fontIndex]);
        if (preferLocaleFonts) {
            if (reorderScripts == null) {
                reorderScripts = new HashMap<String, Short>();
            }
            String[] ss = new String[scripts.length];
            for (int i = 0; i < ss.length; i++) {
                ss[i] = getScriptName(scripts[i]);
                reorderScripts.put(ss[i], scripts[i]);
            }
            reorderSequenceForLocale(ss);
            for (int i = 0; i < ss.length; i++) {
                scripts[i] = reorderScripts.get(ss[i]);
            }
        }
         return scripts;
    }

    private static short[] getFallbackScripts() {
        return getShortArray(head[INDEX_fallbackScripts]);
    }

    private static void printTable(short[] list, int start) {
        for (int i = start; i < list.length; i++) {
            System.out.println("  " + i + " : " + getString(list[i]));
        }
    }

    private static short[] readShortTable(DataInputStream in, int len )
        throws IOException {
        if (len == 0) {
            return EMPTY_SHORT_ARRAY;
        }
        short[] data = new short[len];
        byte[] bb = new byte[len * 2];
        in.read(bb);
        int i = 0,j = 0;
        while (i < len) {
            data[i++] = (short)(bb[j++] << 8 | (bb[j++] & 0xff));
        }
        return data;
    }

    private static void writeShortTable(DataOutputStream out, short[] data)
        throws IOException {
        for (int i = 0; i < data.length; i++) {
            out.writeShort(data[i]);
        }
    }

    private static short[] toList(HashMap map) {
        short[] list = new short[map.size()];
        for (int i = 0; i < list.length; i++) {
            list[i] = -1;
        }
        Iterator iterator = map.entrySet().iterator();
        while (iterator.hasNext()) {
            Entry<String, Short> entry = (Entry <String, Short>)iterator.next();
            list[entry.getValue().shortValue()] = getStringID(entry.getKey());
        }
        return list;
    }

    //runtime cache
    private static String[] stringCache;
    protected static String getString(short stringID) {
        if (stringID == 0)
            return null;
        /*
        if (loadingProperties) {
            return stringTable.substring(stringIDs[stringID],
                                         stringIDs[stringID+1]);
        }
        */
        //sync if we want it to be MT-enabled
        if (stringCache[stringID] == null){
            stringCache[stringID] =
              new String (table_stringTable,
                          table_stringIDs[stringID],
                          table_stringIDs[stringID+1] - table_stringIDs[stringID]);
        }
        return stringCache[stringID];
    }

    private static short[] getShortArray(short shortArrayID) {
        String s = getString(shortArrayID);
        char[] cc = s.toCharArray();
        short[] ss = new short[cc.length];
        for (int i = 0; i < cc.length; i++) {
            ss[i] = (short)(cc[i] & 0xffff);
        }
        return ss;
    }

    private static short getStringID(String s) {
        if (s == null) {
            return (short)0;
        }
        short pos0 = (short)stringTable.length();
        stringTable.append(s);
        short pos1 = (short)stringTable.length();

        stringIDs[stringIDNum] = pos0;
        stringIDs[stringIDNum + 1] = pos1;
        stringIDNum++;
        if (stringIDNum + 1 >= stringIDs.length) {
            short[] tmp = new short[stringIDNum + 1000];
            System.arraycopy(stringIDs, 0, tmp, 0, stringIDNum);
            stringIDs = tmp;
        }
        return (short)(stringIDNum - 1);
    }

    private static short getShortArrayID(short sa[]) {
        char[] cc = new char[sa.length];
        for (int i = 0; i < sa.length; i ++) {
            cc[i] = (char)sa[i];
        }
        String s = new String(cc);
        return getStringID(s);
    }

    //utility "empty" objects
    private static final int[] EMPTY_INT_ARRAY = new int[0];
    private static final String[] EMPTY_STRING_ARRAY = new String[0];
    private static final short[] EMPTY_SHORT_ARRAY = new short[0];
    private static final String UNDEFINED_COMPONENT_FONT = "unknown";

    //////////////////////////////////////////////////////////////////////////
    //Convert the FontConfig data in Properties file to binary data tables  //
    //////////////////////////////////////////////////////////////////////////
    static class PropertiesHandler {
        public void load(InputStream in) throws IOException {
            initLogicalNameStyle();
            initHashMaps();
            FontProperties fp = new FontProperties();
            fp.load(in);
            initBinaryTable();
        }

        private void initBinaryTable() {
            //(0)
            head = new short[HEAD_LENGTH];
            head[INDEX_scriptIDs] = (short)HEAD_LENGTH;

            table_scriptIDs = toList(scriptIDs);
            //(1)a: scriptAllfonts scriptID/allfonts -> componentFontNameID
            //   b: scriptFonts    scriptID -> componentFontNameID[20]
            //if we have a "allfonts.script" def, then we just put
            //the "-platformFontID" value in the slot, otherwise the slot
            //value is "offset" which "offset" is where 20 entries located
            //in the table attached.
            head[INDEX_scriptFonts] = (short)(head[INDEX_scriptIDs]  + table_scriptIDs.length);
            int len = table_scriptIDs.length + scriptFonts.size() * 20;
            table_scriptFonts = new short[len];

            Iterator iterator = scriptAllfonts.entrySet().iterator();
            while (iterator.hasNext()) {
                Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next();
                table_scriptFonts[entry.getKey().intValue()] = (short)entry.getValue().shortValue();
            }
            int off = table_scriptIDs.length;
            iterator = scriptFonts.entrySet().iterator();
            while (iterator.hasNext()) {
                Entry<Short, Short[]> entry = (Entry <Short, Short[]>)iterator.next();
                table_scriptFonts[entry.getKey().intValue()] = (short)-off;
                Short[] v = entry.getValue();
                int i = 0;
                while (i < 20) {
                    if (v[i] != null) {
                        table_scriptFonts[off++] = v[i].shortValue();
                    } else {
                        table_scriptFonts[off++] = 0;
                    }
                    i++;
                }
            }

            //(2)
            head[INDEX_elcIDs] = (short)(head[INDEX_scriptFonts]  + table_scriptFonts.length);
            table_elcIDs = toList(elcIDs);

            //(3) sequences  elcID -> XXXX[1|5] -> scriptID[]
            head[INDEX_sequences] = (short)(head[INDEX_elcIDs]  + table_elcIDs.length);
            table_sequences = new short[elcIDs.size() * NUM_FONTS];
            iterator = sequences.entrySet().iterator();
            while (iterator.hasNext()) {
                Entry<Short, short[]> entry = (Entry <Short, short[]>)iterator.next();
                //table_sequences[entry.getKey().intValue()] = (short)-off;
                int k = entry.getKey().intValue();
                short[] v = entry.getValue();
                /*
                  System.out.println("elc=" + k + "/" + getString((short)table_elcIDs[k]));
                  short[] ss = getShortArray(v[0]);
                  for (int i = 0; i < ss.length; i++) {
                  System.out.println("     " + getString((short)table_scriptIDs[ss[i]]));
                  }
                  */
                if (v.length == 1) {
                    //the "allfonts" entries
                    for (int i = 0; i < NUM_FONTS; i++) {
                        table_sequences[k * NUM_FONTS + i] = v[0];
                    }
                } else {
                    for (int i = 0; i < NUM_FONTS; i++) {
                        table_sequences[k * NUM_FONTS + i] = v[i];
                    }
                }
            }
            //(4)
            head[INDEX_fontfileNameIDs] = (short)(head[INDEX_sequences]  + table_sequences.length);
            table_fontfileNameIDs = toList(fontfileNameIDs);

            //(5)
            head[INDEX_componentFontNameIDs] = (short)(head[INDEX_fontfileNameIDs]  + table_fontfileNameIDs.length);
            table_componentFontNameIDs = toList(componentFontNameIDs);

            //(6)componentFontNameID -> filenameID
            head[INDEX_filenames] = (short)(head[INDEX_componentFontNameIDs]  + table_componentFontNameIDs.length);
            table_filenames = new short[table_componentFontNameIDs.length];
            for (int i = 0; i < table_filenames.length; i++) {
                table_filenames[i] = -1;
            }
            iterator = filenames.entrySet().iterator();
            while (iterator.hasNext()) {
                Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next();
                table_filenames[entry.getKey().shortValue()] = entry.getValue().shortValue();
            }

            //(7)scriptID-> awtfontpath
            //the paths are stored as scriptID -> stringID in awtfontpahts
            head[INDEX_awtfontpaths] = (short)(head[INDEX_filenames]  + table_filenames.length);
            table_awtfontpaths = new short[table_scriptIDs.length];
            iterator = awtfontpaths.entrySet().iterator();
            while (iterator.hasNext()) {
                Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next();
                table_awtfontpaths[entry.getKey().shortValue()] = entry.getValue().shortValue();
            }

            //(8)exclusions
            head[INDEX_exclusions] = (short)(head[INDEX_awtfontpaths]  + table_awtfontpaths.length);
            table_exclusions = new short[scriptIDs.size()];
            iterator = exclusions.entrySet().iterator();
            while (iterator.hasNext()) {
                Entry<Short, int[]> entry = (Entry <Short, int[]>)iterator.next();
                int[] exI = entry.getValue();
                char[] exC = new char[exI.length * 2];
                int j = 0;
                for (int i = 0; i < exI.length; i++) {
                    exC[j++] = (char) (exI[i] >> 16);
                    exC[j++] = (char) (exI[i] & 0xffff);
                }
                table_exclusions[entry.getKey().shortValue()] = getStringID(new String (exC));
            }
            //(9)proportionals
            head[INDEX_proportionals] = (short)(head[INDEX_exclusions]  + table_exclusions.length);
            table_proportionals = new short[proportionals.size() * 2];
            iterator = proportionals.entrySet().iterator();
            int j = 0;
            while (iterator.hasNext()) {
                Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next();
                table_proportionals[j++] = entry.getKey().shortValue();
                table_proportionals[j++] = entry.getValue().shortValue();
            }

            //(10) see (1) for info, the only difference is "xxx.motif"
            head[INDEX_scriptFontsMotif] = (short)(head[INDEX_proportionals] + table_proportionals.length);
            if (scriptAllfontsMotif.size() != 0 || scriptFontsMotif.size() != 0) {
                len = table_scriptIDs.length + scriptFontsMotif.size() * 20;
                table_scriptFontsMotif = new short[len];

                iterator = scriptAllfontsMotif.entrySet().iterator();
                while (iterator.hasNext()) {
                    Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next();
                    table_scriptFontsMotif[entry.getKey().intValue()] =
                      (short)entry.getValue().shortValue();
                }
                off = table_scriptIDs.length;
                iterator = scriptFontsMotif.entrySet().iterator();
                while (iterator.hasNext()) {
                    Entry<Short, Short[]> entry = (Entry <Short, Short[]>)iterator.next();
                    table_scriptFontsMotif[entry.getKey().intValue()] = (short)-off;
                    Short[] v = entry.getValue();
                    int i = 0;
                    while (i < 20) {
                        if (v[i] != null) {
                            table_scriptFontsMotif[off++] = v[i].shortValue();
                        } else {
                            table_scriptFontsMotif[off++] = 0;
                        }
                        i++;
                    }
                }
            } else {
                table_scriptFontsMotif = EMPTY_SHORT_ARRAY;
            }

            //(11)short[] alphabeticSuffix
            head[INDEX_alphabeticSuffix] = (short)(head[INDEX_scriptFontsMotif] + table_scriptFontsMotif.length);
            table_alphabeticSuffix = new short[alphabeticSuffix.size() * 2];
            iterator = alphabeticSuffix.entrySet().iterator();
            j = 0;
            while (iterator.hasNext()) {
                Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next();
                table_alphabeticSuffix[j++] = entry.getKey().shortValue();
                table_alphabeticSuffix[j++] = entry.getValue().shortValue();
            }

            //(15)short[] fallbackScriptIDs; just put the ID in head
            head[INDEX_fallbackScripts] = getShortArrayID(fallbackScriptIDs);

            //(16)appendedfontpath
            head[INDEX_appendedfontpath] = getStringID(appendedfontpath);

            //(17)version
            head[INDEX_version] = getStringID(version);

            //(12)short[] StringIDs
            head[INDEX_stringIDs] = (short)(head[INDEX_alphabeticSuffix] + table_alphabeticSuffix.length);
            table_stringIDs = new short[stringIDNum + 1];
            System.arraycopy(stringIDs, 0, table_stringIDs, 0, stringIDNum + 1);

            //(13)StringTable
            head[INDEX_stringTable] = (short)(head[INDEX_stringIDs] + stringIDNum + 1);
            table_stringTable = stringTable.toString().toCharArray();
            //(14)
            head[INDEX_TABLEEND] = (short)(head[INDEX_stringTable] + stringTable.length());

            //StringTable cache
            stringCache = new String[table_stringIDs.length];
        }

        //////////////////////////////////////////////
        private HashMap<String, Short> scriptIDs;
        //elc -> Encoding.Language.Country
        private HashMap<String, Short> elcIDs;
        //componentFontNameID starts from "1", "0" reserves for "undefined"
        private HashMap<String, Short> componentFontNameIDs;
        private HashMap<String, Short> fontfileNameIDs;
        private HashMap<String, Integer> logicalFontIDs;
        private HashMap<String, Integer> fontStyleIDs;

        //componentFontNameID -> fontfileNameID
        private HashMap<Short, Short>  filenames;

        //elcID -> allfonts/logicalFont -> scriptID list
        //(1)if we have a "allfonts", then the length of the
        //   value array is "1", otherwise it's 5, each font
        //   must have their own individual entry.
        //scriptID list "short[]" is stored as an ID
        private HashMap<Short, short[]> sequences;

        //scriptID ->logicFontID/fontStyleID->componentFontNameID,
        //a 20-entry array (5-name x 4-style) for each script
        private HashMap<Short, Short[]> scriptFonts;

        //scriptID -> componentFontNameID
        private HashMap<Short, Short> scriptAllfonts;

        //scriptID -> exclusionRanges[]
        private HashMap<Short, int[]> exclusions;

        //scriptID -> fontpath
        private HashMap<Short, Short> awtfontpaths;

        //fontID -> fontID
        private HashMap<Short, Short> proportionals;

        //scriptID -> componentFontNameID
        private HashMap<Short, Short> scriptAllfontsMotif;

        //scriptID ->logicFontID/fontStyleID->componentFontNameID,
        private HashMap<Short, Short[]> scriptFontsMotif;

        //elcID -> stringID of alphabetic/XXXX
        private HashMap<Short, Short> alphabeticSuffix;

        private short[] fallbackScriptIDs;
        private String version;
        private String appendedfontpath;

        private void initLogicalNameStyle() {
            logicalFontIDs = new HashMap<String, Integer>();
            fontStyleIDs = new HashMap<String, Integer>();
            logicalFontIDs.put("serif",      0);
            logicalFontIDs.put("sansserif",  1);
            logicalFontIDs.put("monospaced", 2);
            logicalFontIDs.put("dialog",     3);
            logicalFontIDs.put("dialoginput",4);
            fontStyleIDs.put("plain",      0);
            fontStyleIDs.put("bold",       1);
            fontStyleIDs.put("italic",     2);
            fontStyleIDs.put("bolditalic", 3);
        }

        private void initHashMaps() {
            scriptIDs = new HashMap<String, Short>();
            elcIDs = new HashMap<String, Short>();
            componentFontNameIDs = new HashMap<String, Short>();
            /*Init these tables to allow componentFontNameID, fontfileNameIDs
              to start from "1".
            */
            componentFontNameIDs.put("", new Short((short)0));

            fontfileNameIDs = new HashMap<String, Short>();
            filenames = new HashMap<Short, Short>();
            sequences = new HashMap<Short, short[]>();
            scriptFonts = new HashMap<Short, Short[]>();
            scriptAllfonts = new HashMap<Short, Short>();
            exclusions = new HashMap<Short, int[]>();
            awtfontpaths = new HashMap<Short, Short>();
            proportionals = new HashMap<Short, Short>();
            scriptFontsMotif = new HashMap<Short, Short[]>();
            scriptAllfontsMotif = new HashMap<Short, Short>();
            alphabeticSuffix = new HashMap<Short, Short>();
            fallbackScriptIDs = EMPTY_SHORT_ARRAY;
            /*
              version
              appendedfontpath
            */
        }

        private int[] parseExclusions(String key, String exclusions) {
            if (exclusions == null) {
                return EMPTY_INT_ARRAY;
            }
            // range format is xxxx-XXXX,yyyyyy-YYYYYY,.....
            int numExclusions = 1;
            int pos = 0;
            while ((pos = exclusions.indexOf(',', pos)) != -1) {
                numExclusions++;
                pos++;
            }
            int[] exclusionRanges = new int[numExclusions * 2];
            pos = 0;
            int newPos = 0;
            for (int j = 0; j < numExclusions * 2; ) {
                String lower, upper;
                int lo = 0, up = 0;
                try {
                    newPos = exclusions.indexOf('-', pos);
                    lower = exclusions.substring(pos, newPos);
                    pos = newPos + 1;
                    newPos = exclusions.indexOf(',', pos);
                    if (newPos == -1) {
                        newPos = exclusions.length();
                    }
                    upper = exclusions.substring(pos, newPos);
                    pos = newPos + 1;
                    int lowerLength = lower.length();
                    int upperLength = upper.length();
                    if (lowerLength != 4 && lowerLength != 6
                        || upperLength != 4 && upperLength != 6) {
                        throw new Exception();
                    }
                    lo = Integer.parseInt(lower, 16);
                    up = Integer.parseInt(upper, 16);
                    if (lo > up) {
                        throw new Exception();
                    }
                } catch (Exception e) {
                    if (SunGraphicsEnvironment.debugFonts && logger != null) {
                        logger.config("Failed parsing " + key +
                                  " property of font configuration.");

                    }
                    return EMPTY_INT_ARRAY;
                }
                exclusionRanges[j++] = lo;
                exclusionRanges[j++] = up;
            }
            return exclusionRanges;
        }

        private Short getID(HashMap<String, Short> map, String key) {
            Short ret = map.get(key);
            if ( ret == null) {
                map.put(key, (short)map.size());
                return map.get(key);
            }
            return ret;
        }

        class FontProperties extends Properties {
            public synchronized Object put(Object k, Object v) {
                parseProperty((String)k, (String)v);
                return null;
            }
        }

        private void parseProperty(String key, String value) {
            if (key.startsWith("filename.")) {
                //the only special case is "MingLiu_HKSCS" which has "_" in its
                //facename, we dont want to replace the "_" with " "
                key = key.substring(9);
                if (!"MingLiU_HKSCS".equals(key)) {
                    key = key.replace('_', ' ');
                }
                Short faceID = getID(componentFontNameIDs, key);
                Short fileID = getID(fontfileNameIDs, value);
                //System.out.println("faceID=" + faceID + "/" + key + " -> "
                //    + "fileID=" + fileID + "/" + value);
                filenames.put(faceID, fileID);
            } else if (key.startsWith("exclusion.")) {
                key = key.substring(10);
                exclusions.put(getID(scriptIDs,key), parseExclusions(key,value));
            } else if (key.startsWith("sequence.")) {
                key = key.substring(9);
                boolean hasDefault = false;
                boolean has1252 = false;

                //get the scriptID list
                String[] ss = (String[])splitSequence(value).toArray(EMPTY_STRING_ARRAY);
                short [] sa = new short[ss.length];
                for (int i = 0; i < ss.length; i++) {
                    if ("alphabetic/default".equals(ss[i])) {
                        //System.out.println(key + " -> " + ss[i]);
                        ss[i] = "alphabetic";
                        hasDefault = true;
                    } else if ("alphabetic/1252".equals(ss[i])) {
                        //System.out.println(key + " -> " + ss[i]);
                        ss[i] = "alphabetic";
                        has1252 = true;
                    }
                    sa[i] = getID(scriptIDs, ss[i]).shortValue();
                    //System.out.println("scriptID=" + si[i] + "/" + ss[i]);
                }
                //convert the "short[] -> string -> stringID"
                short scriptArrayID = getShortArrayID(sa);
                Short elcID = null;
                int dot = key.indexOf('.');
                if (dot == -1) {
                    if ("fallback".equals(key)) {
                        fallbackScriptIDs = sa;
                        return;
                    }
                    if ("allfonts".equals(key)) {
                        elcID = getID(elcIDs, "NULL.NULL.NULL");
                    } else {
                        if (logger != null) {
                            logger.config("Error sequence def: <sequence." + key + ">");
                        }
                        return;
                    }
                } else {
                    elcID = getID(elcIDs, key.substring(dot + 1));
                    //System.out.println("elcID=" + elcID + "/" + key.substring(dot + 1));
                    key = key.substring(0, dot);
                }
                short[] scriptArrayIDs = null;
                if ("allfonts".equals(key)) {
                    scriptArrayIDs = new short[1];
                    scriptArrayIDs[0] = scriptArrayID;
                } else {
                    scriptArrayIDs = sequences.get(elcID);
                    if (scriptArrayIDs == null) {
                       scriptArrayIDs = new short[5];
                    }
                    Integer fid = logicalFontIDs.get(key);
                    if (fid == null) {
                        if (logger != null) {
                            logger.config("Unrecognizable logicfont name " + key);
                        }
                        return;
                    }
                    //System.out.println("sequence." + key + "/" + id);
                    scriptArrayIDs[fid.intValue()] = scriptArrayID;
                }
                sequences.put(elcID, scriptArrayIDs);
                if (hasDefault) {
                    alphabeticSuffix.put(elcID, getStringID("default"));
                } else
                if (has1252) {
                    alphabeticSuffix.put(elcID, getStringID("1252"));
                }
            } else if (key.startsWith("allfonts.")) {
                key = key.substring(9);
                if (key.endsWith(".motif")) {
                    key = key.substring(0, key.length() - 6);
                    //System.out.println("motif: all." + key + "=" + value);
                    scriptAllfontsMotif.put(getID(scriptIDs,key), getID(componentFontNameIDs,value));
                } else {
                    scriptAllfonts.put(getID(scriptIDs,key), getID(componentFontNameIDs,value));
                }
            } else if (key.startsWith("awtfontpath.")) {
                key = key.substring(12);
                //System.out.println("scriptID=" + getID(scriptIDs, key) + "/" + key);
                awtfontpaths.put(getID(scriptIDs, key), getStringID(value));
            } else if ("version".equals(key)) {
                version = value;
            } else if ("appendedfontpath".equals(key)) {
                appendedfontpath = value;
            } else if (key.startsWith("proportional.")) {
                key = key.substring(13).replace('_', ' ');
                //System.out.println(key + "=" + value);
                proportionals.put(getID(componentFontNameIDs, key),
                                  getID(componentFontNameIDs, value));
            } else {
                //"name.style.script(.motif)", we dont care anything else
                int dot1, dot2;
                boolean isMotif = false;

                dot1 = key.indexOf('.');
                if (dot1 == -1) {
                    if (logger != null) {
                        logger.config("Failed parsing " + key +
                                  " property of font configuration.");

                    }
                    return;
                }
                dot2 = key.indexOf('.', dot1 + 1);
                if (dot2 == -1) {
                    if (logger != null) {
                        logger.config("Failed parsing " + key +
                                  " property of font configuration.");

                    }
                    return;
                }
                if (key.endsWith(".motif")) {
                    key = key.substring(0, key.length() - 6);
                    isMotif = true;
                    //System.out.println("motif: " + key + "=" + value);
                }
                Integer nameID = logicalFontIDs.get(key.substring(0, dot1));
                Integer styleID = fontStyleIDs.get(key.substring(dot1+1, dot2));
                Short scriptID = getID(scriptIDs, key.substring(dot2 + 1));
                if (nameID == null || styleID == null) {
                    if (logger != null) {
                        logger.config("unrecognizable logicfont name/style at " + key);
                    }
                    return;
                }
                Short[] pnids;
                if (isMotif) {
                    pnids = scriptFontsMotif.get(scriptID);
                } else {
                    pnids = scriptFonts.get(scriptID);
                }
                if (pnids == null) {
                    pnids =  new Short[20];
                }
                pnids[nameID.intValue() * NUM_STYLES + styleID.intValue()]
                  = getID(componentFontNameIDs, value);
                /*
                System.out.println("key=" + key + "/<" + nameID + "><" + styleID
                                     + "><" + scriptID + ">=" + value
                                     + "/" + getID(componentFontNameIDs, value));
                */
                if (isMotif) {
                    scriptFontsMotif.put(scriptID, pnids);
                } else {
                    scriptFonts.put(scriptID, pnids);
                }
            }
        }
    }
}
