/*
 * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.font;

import java.awt.Font;
import java.awt.FontFormatException;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;

import javax.swing.plaf.FontUIResource;

import sun.awt.FontConfiguration;
import sun.awt.SunToolkit;
import sun.awt.util.ThreadGroupUtils;
import sun.java2d.FontSupport;
import sun.util.logging.PlatformLogger;

/**
 * The base implementation of the {@link FontManager} interface. It implements
 * the platform independent, shared parts of OpenJDK's FontManager
 * implementations. The platform specific parts are declared as abstract
 * methods that have to be implemented by specific implementations.
 */
public abstract class SunFontManager implements FontSupport, FontManagerForSGE {

    private static class TTFilter implements FilenameFilter {
        public boolean accept(File dir,String name) {
            /* all conveniently have the same suffix length */
            int offset = name.length()-4;
            if (offset <= 0) { /* must be at least A.ttf */
                return false;
            } else {
                return(name.startsWith(".ttf", offset) ||
                       name.startsWith(".TTF", offset) ||
                       name.startsWith(".ttc", offset) ||
                       name.startsWith(".TTC", offset) ||
                       name.startsWith(".otf", offset) ||
                       name.startsWith(".OTF", offset));
            }
        }
    }

    private static class T1Filter implements FilenameFilter {
        public boolean accept(File dir,String name) {
            if (noType1Font) {
                return false;
            }
            /* all conveniently have the same suffix length */
            int offset = name.length()-4;
            if (offset <= 0) { /* must be at least A.pfa */
                return false;
            } else {
                return(name.startsWith(".pfa", offset) ||
                       name.startsWith(".pfb", offset) ||
                       name.startsWith(".PFA", offset) ||
                       name.startsWith(".PFB", offset));
            }
        }
    }

     private static class TTorT1Filter implements FilenameFilter {
        public boolean accept(File dir, String name) {

            /* all conveniently have the same suffix length */
            int offset = name.length()-4;
            if (offset <= 0) { /* must be at least A.ttf or A.pfa */
                return false;
            } else {
                boolean isTT =
                    name.startsWith(".ttf", offset) ||
                    name.startsWith(".TTF", offset) ||
                    name.startsWith(".ttc", offset) ||
                    name.startsWith(".TTC", offset) ||
                    name.startsWith(".otf", offset) ||
                    name.startsWith(".OTF", offset);
                if (isTT) {
                    return true;
                } else if (noType1Font) {
                    return false;
                } else {
                    return(name.startsWith(".pfa", offset) ||
                           name.startsWith(".pfb", offset) ||
                           name.startsWith(".PFA", offset) ||
                           name.startsWith(".PFB", offset));
                }
            }
        }
    }

    private static Font2DHandle FONT_HANDLE_NULL = new Font2DHandle(null);

    public static final int FONTFORMAT_NONE = -1;
    public static final int FONTFORMAT_TRUETYPE = 0;
    public static final int FONTFORMAT_TYPE1 = 1;
    public static final int FONTFORMAT_TTC = 2;
    public static final int FONTFORMAT_COMPOSITE = 3;
    public static final int FONTFORMAT_NATIVE = 4;

    /* Pool of 20 font file channels chosen because some UTF-8 locale
     * composite fonts can use up to 16 platform fonts (including the
     * Lucida fall back). This should prevent channel thrashing when
     * dealing with one of these fonts.
     * The pool array stores the fonts, rather than directly referencing
     * the channels, as the font needs to do the open/close work.
     */
    // MACOSX begin -- need to access these in subclass
    protected static final int CHANNELPOOLSIZE = 20;
    protected FileFont[] fontFileCache = new FileFont[CHANNELPOOLSIZE];
    // MACOSX end
    private int lastPoolIndex = 0;

    /* Need to implement a simple linked list scheme for fast
     * traversal and lookup.
     * Also want to "fast path" dialog so there's minimal overhead.
     */
    /* There are at exactly 20 composite fonts: 5 faces (but some are not
     * usually different), in 4 styles. The array may be auto-expanded
     * later if more are needed, eg for user-defined composites or locale
     * variants.
     */
    private int maxCompFont = 0;
    private CompositeFont [] compFonts = new CompositeFont[20];
    private ConcurrentHashMap<String, CompositeFont>
        compositeFonts = new ConcurrentHashMap<>();
    private ConcurrentHashMap<String, PhysicalFont>
        physicalFonts = new ConcurrentHashMap<>();
    private ConcurrentHashMap<String, PhysicalFont>
        registeredFonts = new ConcurrentHashMap<>();

    /* given a full name find the Font. Remind: there's duplication
     * here in that this contains the content of compositeFonts +
     * physicalFonts.
     */
    // MACOSX begin -- need to access this in subclass
    protected ConcurrentHashMap<String, Font2D>
        fullNameToFont = new ConcurrentHashMap<>();
    // MACOSX end

    /* TrueType fonts have localised names. Support searching all
     * of these before giving up on a name.
     */
    private HashMap<String, TrueTypeFont> localeFullNamesToFont;

    private PhysicalFont defaultPhysicalFont;

    static boolean longAddresses;
    private boolean loaded1dot0Fonts = false;
    boolean loadedAllFonts = false;
    boolean loadedAllFontFiles = false;
    String[] jreOtherFontFiles;
    boolean noOtherJREFontFiles = false; // initial assumption.

    public static String jreLibDirName;
    public static String jreFontDirName;
    private static HashSet<String> missingFontFiles = null;
    private String defaultFontName;
    private String defaultFontFileName;
    protected HashSet<String> registeredFontFiles = new HashSet<>();

    private ArrayList<String> badFonts;
    /* fontPath is the location of all fonts on the system, excluding the
     * JRE's own font directory but including any path specified using the
     * sun.java2d.fontpath property. Together with that property,  it is
     * initialised by the getPlatformFontPath() method
     * This call must be followed by a call to registerFontDirs(fontPath)
     * once any extra debugging path has been appended.
     */
    protected String fontPath;
    private FontConfiguration fontConfig;
    /* discoveredAllFonts is set to true when all fonts on the font path are
     * discovered. This usually also implies opening, validating and
     * registering, but an implementation may be optimized to avold this.
     * So see also "loadedAllFontFiles"
     */
    private boolean discoveredAllFonts = false;

    /* No need to keep consing up new instances - reuse a singleton.
     * The trade-off is that these objects don't get GC'd.
     */
    private static final FilenameFilter ttFilter = new TTFilter();
    private static final FilenameFilter t1Filter = new T1Filter();

    private Font[] allFonts;
    private String[] allFamilies; // cache for default locale only
    private Locale lastDefaultLocale;

    public static boolean noType1Font;

    /* Used to indicate required return type from toArray(..); */
    private static String[] STR_ARRAY = new String[0];

    /**
     * Returns the global SunFontManager instance. This is similar to
     * {@link FontManagerFactory#getInstance()} but it returns a
     * SunFontManager instance instead. This is only used in internal classes
     * where we can safely assume that a SunFontManager is to be used.
     *
     * @return the global SunFontManager instance
     */
    public static SunFontManager getInstance() {
        FontManager fm = FontManagerFactory.getInstance();
        return (SunFontManager) fm;
    }

    public FilenameFilter getTrueTypeFilter() {
        return ttFilter;
    }

    public FilenameFilter getType1Filter() {
        return t1Filter;
    }

    /* After we reach MAXSOFTREFCNT, use weak refs for created fonts.
     * This means that a small number of created fonts as used in a UI app
     * will not be eagerly collected, but an app that create many will
     * have them collected more frequently to reclaim storage.
     */
    private static int maxSoftRefCnt = 10;

    static {
        initStatic();
    }

    private static void initStatic() {
        FontManagerNativeLibrary.load();

        // JNI throws an exception if a class/method/field is not found,
        // so there's no need to do anything explicit here.
        initIDs();

        switch (StrikeCache.nativeAddressSize) {
        case 8: longAddresses = true; break;
        case 4: longAddresses = false; break;
        default: throw new RuntimeException("Unexpected address size");
        }

        noType1Font = "true".equals(System.getProperty("sun.java2d.noType1Font"));
        jreLibDirName = System.getProperty("java.home","") + File.separator + "lib";
        jreFontDirName = jreLibDirName + File.separator + "fonts";

        maxSoftRefCnt = Integer.getInteger("sun.java2d.font.maxSoftRefs", 10);
    }

    /**
     * If the module image layout changes the location of JDK fonts,
     * this will be updated to reflect that.
     */
    public static final String getJDKFontDir() {
        return jreFontDirName;
    }

    public TrueTypeFont getEUDCFont() {
        // Overridden in Windows.
        return null;
    }

    /* Initialise ptrs used by JNI methods */
    private static native void initIDs();

    protected SunFontManager() {
        File badFontFile =
            new File(jreFontDirName + File.separator + "badfonts.txt");
        if (badFontFile.exists()) {
            badFonts = new ArrayList<>();
            try (FileInputStream fis = new FileInputStream(badFontFile);
                 BufferedReader br = new BufferedReader(new InputStreamReader(fis))) {
                while (true) {
                    String name = br.readLine();
                    if (name == null) {
                        break;
                    } else {
                        if (FontUtilities.debugFonts()) {
                            FontUtilities.logWarning("read bad font: " + name);
                        }
                        badFonts.add(name);
                    }
                }
            } catch (IOException e) {
            }
        }

        /* Here we get the fonts in jre/lib/fonts and register
         * them so they are always available and preferred over
         * other fonts. This needs to be registered before the
         * composite fonts as otherwise some native font that
         * corresponds may be found as we don't have a way to
         * handle two fonts of the same name, so the JRE one
         * must be the first one registered. Pass "true" to
         * registerFonts method as on-screen these JRE fonts
         * always go through the JDK rasteriser.
         */
        if (FontUtilities.isLinux) {
            /* Linux font configuration uses these fonts */
            registerFontDir(jreFontDirName);
        }
        registerFontsInDir(jreFontDirName, true, Font2D.JRE_RANK,
                           true, false);

        /* Create the font configuration and get any font path
         * that might be specified.
         */
        fontConfig = createFontConfiguration();

        String[] fontInfo = getDefaultPlatformFont();
        defaultFontName = fontInfo[0];
        if (defaultFontName == null && FontUtilities.debugFonts()) {
            FontUtilities.logWarning("defaultFontName is null");
        }
        defaultFontFileName = fontInfo[1];

        String extraFontPath = fontConfig.getExtraFontPath();

        /* In prior releases the debugging font path replaced
         * all normally located font directories except for the
         * JRE fonts dir. This directory is still always located
         * and placed at the head of the path but as an
         * augmentation to the previous behaviour the
         * changes below allow you to additionally append to
         * the font path by starting with append: or prepend by
         * starting with a prepend: sign. Eg: to append
         * -Dsun.java2d.fontpath=append:/usr/local/myfonts
         * and to prepend
         * -Dsun.java2d.fontpath=prepend:/usr/local/myfonts Disp
         *
         * If there is an appendedfontpath it in the font
         * configuration it is used instead of searching the
         * system for dirs.
         * The behaviour of append and prepend is then similar
         * to the normal case. ie it goes after what
         * you prepend and * before what you append. If the
         * sun.java2d.fontpath property is used, but it
         * neither the append or prepend syntaxes is used then
         * as except for the JRE dir the path is replaced and it
         * is up to you to make sure that all the right
         * directories are located. This is platform and
         * locale-specific so its almost impossible to get
         * right, so it should be used with caution.
         */
        boolean prependToPath = false;
        boolean appendToPath = false;
        String dbgFontPath = System.getProperty("sun.java2d.fontpath");

        if (dbgFontPath != null) {
            if (dbgFontPath.startsWith("prepend:")) {
                prependToPath = true;
                dbgFontPath =
                    dbgFontPath.substring("prepend:".length());
            } else if (dbgFontPath.startsWith("append:")) {
                appendToPath = true;
                dbgFontPath =
                    dbgFontPath.substring("append:".length());
            }
        }

        if (FontUtilities.debugFonts()) {
            FontUtilities.logInfo("JRE font directory: " + jreFontDirName);
            FontUtilities.logInfo("Extra font path: " + extraFontPath);
            FontUtilities.logInfo("Debug font path: " + dbgFontPath);
        }

        if (dbgFontPath != null) {
            /* In debugging mode we register all the paths
             * Caution: this is a very expensive call on Solaris:-
             */
            fontPath = getPlatformFontPath(noType1Font);

            if (extraFontPath != null) {
                fontPath = extraFontPath + File.pathSeparator + fontPath;
            }
            if (appendToPath) {
                fontPath += File.pathSeparator + dbgFontPath;
            } else if (prependToPath) {
                fontPath = dbgFontPath + File.pathSeparator + fontPath;
            } else {
                fontPath = dbgFontPath;
            }
            registerFontDirs(fontPath);
        } else if (extraFontPath != null) {
            /* If the font configuration contains an
             * "appendedfontpath" entry, it is interpreted as a
             * set of locations that should always be registered.
             * It may be additional to locations normally found
             * for that place, or it may be locations that need
             * to have all their paths registered to locate all
             * the needed platform names.
             * This is typically when the same .TTF file is
             * referenced from multiple font.dir files and all
             * of these must be read to find all the native
             * (XLFD) names for the font, so that X11 font APIs
             * can be used for as many code points as possible.
             */
            registerFontDirs(extraFontPath);
        }

        initCompositeFonts(fontConfig, null);
    }

    public Font2DHandle getNewComposite(String family, int style,
                                        Font2DHandle handle) {

        if (!(handle.font2D instanceof CompositeFont)) {
            return handle;
        }

        CompositeFont oldComp = (CompositeFont)handle.font2D;
        PhysicalFont oldFont = oldComp.getSlotFont(0);

        if (family == null) {
            family = oldFont.getFamilyName(null);
        }
        if (style == -1) {
            style = oldComp.getStyle();
        }

        Font2D newFont = findFont2D(family, style, NO_FALLBACK);
        if (!(newFont instanceof PhysicalFont)) {
            newFont = oldFont;
        }
        PhysicalFont physicalFont = (PhysicalFont)newFont;
        CompositeFont dialog2D =
            (CompositeFont)findFont2D("dialog", style, NO_FALLBACK);
        if (dialog2D == null) { /* shouldn't happen */
            return handle;
        }
        CompositeFont compFont = new CompositeFont(physicalFont, dialog2D);
        Font2DHandle newHandle = new Font2DHandle(compFont);
        return newHandle;
    }

    protected void registerCompositeFont(String compositeName,
                                      String[] componentFileNames,
                                      String[] componentNames,
                                      int numMetricsSlots,
                                      int[] exclusionRanges,
                                      int[] exclusionMaxIndex,
                                      boolean defer) {

        CompositeFont cf = new CompositeFont(compositeName,
                                             componentFileNames,
                                             componentNames,
                                             numMetricsSlots,
                                             exclusionRanges,
                                             exclusionMaxIndex, defer, this);
        addCompositeToFontList(cf, Font2D.FONT_CONFIG_RANK);
        synchronized (compFonts) {
            compFonts[maxCompFont++] = cf;
        }
    }

    /* This variant is used only when the application specifies
     * a variant of composite fonts which prefers locale specific or
     * proportional fonts.
     */
    protected static void registerCompositeFont(String compositeName,
                                                String[] componentFileNames,
                                                String[] componentNames,
                                                int numMetricsSlots,
                                                int[] exclusionRanges,
                                                int[] exclusionMaxIndex,
                                                boolean defer,
                                                ConcurrentHashMap<String, Font2D>
                                                altNameCache) {

        CompositeFont cf = new CompositeFont(compositeName,
                                             componentFileNames,
                                             componentNames,
                                             numMetricsSlots,
                                             exclusionRanges,
                                             exclusionMaxIndex, defer,
                                             SunFontManager.getInstance());

        /* if the cache has an existing composite for this case, make
         * its handle point to this new font.
         * This ensures that when the altNameCache that is passed in
         * is the global mapNameCache - ie we are running as an application -
         * that any statically created java.awt.Font instances which already
         * have a Font2D instance will have that re-directed to the new Font
         * on subsequent uses. This is particularly important for "the"
         * default font instance, or similar cases where a UI toolkit (eg
         * Swing) has cached a java.awt.Font. Note that if Swing is using
         * a custom composite APIs which update the standard composites have
         * no effect - this is typically the case only when using the Windows
         * L&F where these APIs would conflict with that L&F anyway.
         */
        Font2D oldFont =altNameCache.get(compositeName.toLowerCase(Locale.ENGLISH));
        if (oldFont instanceof CompositeFont) {
            oldFont.handle.font2D = cf;
        }
        altNameCache.put(compositeName.toLowerCase(Locale.ENGLISH), cf);
    }

    private void addCompositeToFontList(CompositeFont f, int rank) {
        if (FontUtilities.isLogging()) {
            FontUtilities.logInfo("Add to Family " + f.familyName +
                        ", Font " + f.fullName + " rank=" + rank);
        }
        f.setRank(rank);
        compositeFonts.put(f.fullName, f);
        fullNameToFont.put(f.fullName.toLowerCase(Locale.ENGLISH), f);

        FontFamily family = FontFamily.getFamily(f.familyName);
        if (family == null) {
            family = new FontFamily(f.familyName, true, rank);
        }
        family.setFont(f, f.style);
    }

    /*
     * Systems may have fonts with the same name.
     * We want to register only one of such fonts (at least until
     * such time as there might be APIs which can accommodate > 1).
     * Rank is 1) font configuration fonts, 2) JRE fonts, 3) OT/TT fonts,
     * 4) Type1 fonts, 5) native fonts.
     *
     * If the new font has the same name as the old font, the higher
     * ranked font gets added, replacing the lower ranked one.
     * If the fonts are of equal rank, then make a special case of
     * font configuration rank fonts, which are on closer inspection,
     * OT/TT fonts such that the larger font is registered. This is
     * a heuristic since a font may be "larger" in the sense of more
     * code points, or be a larger "file" because it has more bitmaps.
     * So it is possible that using filesize may lead to less glyphs, and
     * using glyphs may lead to lower quality display. Probably number
     * of glyphs is the ideal, but filesize is information we already
     * have and is good enough for the known cases.
     * Also don't want to register fonts that match JRE font families
     * but are coming from a source other than the JRE.
     * This will ensure that we will algorithmically style the JRE
     * plain font and get the same set of glyphs for all styles.
     *
     * Note that this method returns a value
     * if it returns the same object as its argument that means this
     * font was newly registered.
     * If it returns a different object it means this font already exists,
     * and you should use that one.
     * If it returns null means this font was not registered and none
     * in that name is registered. The caller must find a substitute
     */
    // MACOSX begin -- need to access this in subclass
    protected PhysicalFont addToFontList(PhysicalFont f, int rank) {
    // MACOSX end

        String fontName = f.fullName;
        String familyName = f.familyName;
        if (fontName == null || fontName.isEmpty()) {
            return null;
        }
        if (compositeFonts.containsKey(fontName)) {
            /* Don't register any font that has the same name as a composite */
            return null;
        }
        f.setRank(rank);
        if (!physicalFonts.containsKey(fontName)) {
            if (FontUtilities.isLogging()) {
                FontUtilities.logInfo("Add to Family " + familyName +
                            ", Font " + fontName + " rank=" + rank);
            }
            physicalFonts.put(fontName, f);
            FontFamily family = FontFamily.getFamily(familyName);
            if (family == null) {
                family = new FontFamily(familyName, false, rank);
                family.setFont(f, f.style);
            } else {
                family.setFont(f, f.style);
            }
            fullNameToFont.put(fontName.toLowerCase(Locale.ENGLISH), f);
            return f;
        } else {
            PhysicalFont newFont = f;
            PhysicalFont oldFont = physicalFonts.get(fontName);
            if (oldFont == null) {
                return null;
            }
            /* If the new font is of an equal or higher rank, it is a
             * candidate to replace the current one, subject to further tests.
             */
            if (oldFont.getRank() >= rank) {

                /* All fonts initialise their mapper when first
                 * used. If the mapper is non-null then this font
                 * has been accessed at least once. In that case
                 * do not replace it. This may be overly stringent,
                 * but its probably better not to replace a font that
                 * someone is already using without a compelling reason.
                 * Additionally the primary case where it is known
                 * this behaviour is important is in certain composite
                 * fonts, and since all the components of a given
                 * composite are usually initialised together this
                 * is unlikely. For this to be a problem, there would
                 * have to be a case where two different composites used
                 * different versions of the same-named font, and they
                 * were initialised and used at separate times.
                 * In that case we continue on and allow the new font to
                 * be installed, but replaceFont will continue to allow
                 * the original font to be used in Composite fonts.
                 */
                if (oldFont.mapper != null && rank > Font2D.FONT_CONFIG_RANK) {
                    return oldFont;
                }

                /* Normally we require a higher rank to replace a font,
                 * but as a special case, if the two fonts are the same rank,
                 * and are instances of TrueTypeFont we want the
                 * more complete (larger) one.
                 */
                if (oldFont.getRank() == rank) {
                    if (oldFont instanceof TrueTypeFont &&
                        newFont instanceof TrueTypeFont) {
                        TrueTypeFont oldTTFont = (TrueTypeFont)oldFont;
                        TrueTypeFont newTTFont = (TrueTypeFont)newFont;
                        if (oldTTFont.fileSize >= newTTFont.fileSize) {
                            return oldFont;
                        }
                    } else {
                        return oldFont;
                    }
                }
                /* Don't replace ever JRE fonts.
                 * This test is in case a font configuration references
                 * a Lucida font, which has been mapped to a Lucida
                 * from the host O/S. The assumption here is that any
                 * such font configuration file is probably incorrect, or
                 * the host O/S version is for the use of AWT.
                 * In other words if we reach here, there's a possible
                 * problem with our choice of font configuration fonts.
                 */
                if (oldFont.platName.startsWith(jreFontDirName)) {
                    if (FontUtilities.isLogging()) {
                        FontUtilities.logWarning("Unexpected attempt to replace a JRE " +
                                       " font " + fontName + " from " + oldFont.platName +
                                       " with " + newFont.platName);
                    }
                    return oldFont;
                }

                if (FontUtilities.isLogging()) {
                    FontUtilities.logInfo("Replace in Family " + familyName +
                                    ",Font " + fontName + " new rank="+rank +
                                    " from " + oldFont.platName +
                                    " with " + newFont.platName);
                }
                replaceFont(oldFont, newFont);
                physicalFonts.put(fontName, newFont);
                fullNameToFont.put(fontName.toLowerCase(Locale.ENGLISH),
                                   newFont);

                FontFamily family = FontFamily.getFamily(familyName);
                if (family == null) {
                    family = new FontFamily(familyName, false, rank);
                    family.setFont(newFont, newFont.style);
                } else {
                    family.setFont(newFont, newFont.style);
                }
                return newFont;
            } else {
                return oldFont;
            }
        }
    }

    public Font2D[] getRegisteredFonts() {
        PhysicalFont[] physFonts = getPhysicalFonts();
        int mcf = maxCompFont; /* for MT-safety */
        Font2D[] regFonts = new Font2D[physFonts.length+mcf];
        System.arraycopy(compFonts, 0, regFonts, 0, mcf);
        System.arraycopy(physFonts, 0, regFonts, mcf, physFonts.length);
        return regFonts;
    }

    protected PhysicalFont[] getPhysicalFonts() {
        return physicalFonts.values().toArray(new PhysicalFont[0]);
    }


    /* The class FontRegistrationInfo is used when a client says not
     * to register a font immediately. This mechanism is used to defer
     * initialisation of all the components of composite fonts at JRE
     * start-up. The CompositeFont class is "aware" of this and when it
     * is first used it asks for the registration of its components.
     * Also in the event that any physical font is requested the
     * deferred fonts are initialised before triggering a search of the
     * system.
     * Two maps are used. One to track the deferred fonts. The
     * other to track the fonts that have been initialised through this
     * mechanism.
     */

    private static final class FontRegistrationInfo {

        String fontFilePath;
        String[] nativeNames;
        int fontFormat;
        boolean javaRasterizer;
        int fontRank;

        FontRegistrationInfo(String fontPath, String[] names, int format,
                             boolean useJavaRasterizer, int rank) {
            this.fontFilePath = fontPath;
            this.nativeNames = names;
            this.fontFormat = format;
            this.javaRasterizer = useJavaRasterizer;
            this.fontRank = rank;
        }
    }

    private final ConcurrentHashMap<String, FontRegistrationInfo>
        deferredFontFiles = new ConcurrentHashMap<>();
    private final ConcurrentHashMap<String, Font2DHandle>
        initialisedFonts = new ConcurrentHashMap<>();

    /* Remind: possibly enhance initialiseDeferredFonts() to be
     * optionally given a name and a style and it could stop when it
     * finds that font - but this would be a problem if two of the
     * fonts reference the same font face name (cf the Solaris
     * euro fonts).
     */
    protected synchronized void initialiseDeferredFonts() {
        for (String fileName : deferredFontFiles.keySet()) {
            initialiseDeferredFont(fileName);
        }
    }

    protected synchronized void registerDeferredJREFonts(String jreDir) {
        for (FontRegistrationInfo info : deferredFontFiles.values()) {
            if (info.fontFilePath != null &&
                info.fontFilePath.startsWith(jreDir)) {
                initialiseDeferredFont(info.fontFilePath);
            }
        }
    }

    public boolean isDeferredFont(String fileName) {
        return deferredFontFiles.containsKey(fileName);
    }

    PhysicalFont findJREDeferredFont(String name, int style) {

        /* Iterate over the deferred font files looking for any in the
         * jre directory that we didn't recognise, open each of these.
         * In almost all installations this will quickly fall through
         * because jreOtherFontFiles will be empty.
         * noOtherJREFontFiles is used so we can skip this block as soon
         * as its determined that it's not needed - almost always after the
         * very first time through.
         */
        if (noOtherJREFontFiles) {
            return null;
        }
        synchronized (jreFontDirName) {
            if (jreOtherFontFiles == null) {
                HashSet<String> otherFontFiles = new HashSet<>();
                for (String deferredFile : deferredFontFiles.keySet()) {
                    File file = new File(deferredFile);
                    String dir = file.getParent();
                    /* skip names which aren't absolute, aren't in the JRE
                     * directory, or are known Lucida fonts.
                     */
                    if (dir == null || !dir.equals(jreFontDirName)) {
                        continue;
                    }
                    otherFontFiles.add(deferredFile);
                }
                jreOtherFontFiles = otherFontFiles.toArray(STR_ARRAY);
                if (jreOtherFontFiles.length == 0) {
                    noOtherJREFontFiles = true;
                }
            }

            for (int i=0; i<jreOtherFontFiles.length;i++) {
                String fileName = jreOtherFontFiles[i];
                if (fileName == null) {
                    continue;
                }
                jreOtherFontFiles[i] = null;
                PhysicalFont physicalFont = initialiseDeferredFont(fileName);
                if (physicalFont != null &&
                    (physicalFont.getFontName(null).equalsIgnoreCase(name) ||
                     physicalFont.getFamilyName(null).equalsIgnoreCase(name))
                    && physicalFont.style == style) {
                    return physicalFont;
                }
            }
        }

        return null;
    }

    private PhysicalFont findOtherDeferredFont(String name, int style) {
        for (String fileName : deferredFontFiles.keySet()) {
            PhysicalFont physicalFont = initialiseDeferredFont(fileName);
            if (physicalFont != null &&
                (physicalFont.getFontName(null).equalsIgnoreCase(name) ||
                physicalFont.getFamilyName(null).equalsIgnoreCase(name)) &&
                physicalFont.style == style) {
                return physicalFont;
            }
        }
        return null;
    }

    private PhysicalFont findDeferredFont(String name, int style) {
        PhysicalFont physicalFont = findJREDeferredFont(name, style);
        if (physicalFont != null) {
            return physicalFont;
        } else {
            return findOtherDeferredFont(name, style);
        }
    }

    public void registerDeferredFont(String fileNameKey,
                                     String fullPathName,
                                     String[] nativeNames,
                                     int fontFormat,
                                     boolean useJavaRasterizer,
                                     int fontRank) {
        FontRegistrationInfo regInfo =
            new FontRegistrationInfo(fullPathName, nativeNames, fontFormat,
                                     useJavaRasterizer, fontRank);
        deferredFontFiles.put(fileNameKey, regInfo);
    }


    public synchronized
         PhysicalFont initialiseDeferredFont(String fileNameKey) {

        if (fileNameKey == null) {
            return null;
        }
        if (FontUtilities.isLogging()) {
            FontUtilities.logInfo("Opening deferred font file " + fileNameKey);
        }

        PhysicalFont physicalFont = null;
        FontRegistrationInfo regInfo = deferredFontFiles.get(fileNameKey);
        if (regInfo != null) {
            deferredFontFiles.remove(fileNameKey);
            physicalFont = registerFontFile(regInfo.fontFilePath,
                                            regInfo.nativeNames,
                                            regInfo.fontFormat,
                                            regInfo.javaRasterizer,
                                            regInfo.fontRank);

            if (physicalFont != null) {
                /* Store the handle, so that if a font is bad, we
                 * retrieve the substituted font.
                 */
                initialisedFonts.put(fileNameKey, physicalFont.handle);
            } else {
                initialisedFonts.put(fileNameKey, FONT_HANDLE_NULL);
            }
        } else {
            Font2DHandle handle = initialisedFonts.get(fileNameKey);
            if (handle == null) {
                /* Probably shouldn't happen, but just in case */
                initialisedFonts.put(fileNameKey, FONT_HANDLE_NULL);
            } else {
                physicalFont = (PhysicalFont)(handle.font2D);
            }
        }
        return physicalFont;
    }

    public boolean isRegisteredFontFile(String name) {
        return registeredFonts.containsKey(name);
    }

    public PhysicalFont getRegisteredFontFile(String name) {
        return registeredFonts.get(name);
    }

    /* Note that the return value from this method is not always
     * derived from this file, and may be null. See addToFontList for
     * some explanation of this.
     */
    public PhysicalFont registerFontFile(String fileName,
                                         String[] nativeNames,
                                         int fontFormat,
                                         boolean useJavaRasterizer,
                                         int fontRank) {

        PhysicalFont regFont = registeredFonts.get(fileName);
        if (regFont != null) {
            return regFont;
        }

        PhysicalFont physicalFont = null;
        try {
            switch (fontFormat) {

            case FONTFORMAT_TRUETYPE:
                int fn = 0;
                TrueTypeFont ttf;
                do {
                    ttf = new TrueTypeFont(fileName, nativeNames, fn++,
                                           useJavaRasterizer);
                    PhysicalFont pf = addToFontList(ttf, fontRank);
                    if (physicalFont == null) {
                        physicalFont = pf;
                    }
                }
                while (fn < ttf.getFontCount());
                break;

            case FONTFORMAT_TYPE1:
                Type1Font t1f = new Type1Font(fileName, nativeNames);
                physicalFont = addToFontList(t1f, fontRank);
                break;

            case FONTFORMAT_NATIVE:
                NativeFont nf = new NativeFont(fileName, false);
                physicalFont = addToFontList(nf, fontRank);
                break;
            default:

            }
            if (FontUtilities.isLogging()) {
                FontUtilities.logInfo("Registered file " + fileName + " as font " +
                                physicalFont + " rank="  + fontRank);
            }
        } catch (FontFormatException ffe) {
            if (FontUtilities.isLogging()) {
                FontUtilities.logInfo("Unusable font: " + fileName + " " + ffe.toString());
            }
        }
        if (physicalFont != null &&
            fontFormat != FONTFORMAT_NATIVE) {
            registeredFonts.put(fileName, physicalFont);
        }
        return physicalFont;
    }

    public void registerFonts(String[] fileNames,
                              String[][] nativeNames,
                              int fontCount,
                              int fontFormat,
                              boolean useJavaRasterizer,
                              int fontRank, boolean defer) {

        for (int i=0; i < fontCount; i++) {
            if (defer) {
                registerDeferredFont(fileNames[i],fileNames[i], nativeNames[i],
                                     fontFormat, useJavaRasterizer, fontRank);
            } else {
                registerFontFile(fileNames[i], nativeNames[i],
                                 fontFormat, useJavaRasterizer, fontRank);
            }
        }
    }

    /*
     * This is the Physical font used when some other font on the system
     * can't be located. There has to be at least one font or the font
     * system is not useful and the graphics environment cannot sustain
     * the Java platform.
     */
    public PhysicalFont getDefaultPhysicalFont() {
        if (defaultPhysicalFont == null) {
            String defaultFontName = getDefaultFontFaceName();
            // findFont2D will load all fonts
            Font2D font2d = findFont2D(defaultFontName, Font.PLAIN, NO_FALLBACK);
            if (font2d != null) {
                if (font2d instanceof PhysicalFont) {
                    defaultPhysicalFont = (PhysicalFont)font2d;
                } else {
                    if (FontUtilities.isLogging()) {
                        FontUtilities.logWarning("Font returned by findFont2D for default font name " +
                                     defaultFontName + " is not a physical font: " + font2d.getFontName(null));
                    }
                }
            }
            if (defaultPhysicalFont == null) {
                /* Because of the findFont2D call above, if we reach here, we
                 * know all fonts have already been loaded, just accept any
                 * match at this point. If this fails we are in real trouble
                 * and I don't know how to recover from there being absolutely
                 * no fonts anywhere on the system.
                 */
                defaultPhysicalFont = physicalFonts.values().stream().findFirst()
                    .orElseThrow(()->new Error("Probable fatal error: No physical fonts found."));
            }
        }
        return defaultPhysicalFont;
    }

    public Font2D getDefaultLogicalFont(int style) {
        return findFont2D("dialog", style, NO_FALLBACK);
    }

    /*
     * return String representation of style prepended with "."
     * This is useful for performance to avoid unnecessary string operations.
     */
    private static String dotStyleStr(int num) {
        switch(num){
          case Font.BOLD:
            return ".bold";
          case Font.ITALIC:
            return ".italic";
          case Font.ITALIC | Font.BOLD:
            return ".bolditalic";
          default:
            return ".plain";
        }
    }

    /* This is implemented only on windows and is called from code that
     * executes only on windows. This isn't pretty but its not a precedent
     * in this file. This very probably should be cleaned up at some point.
     */
    protected void
        populateFontFileNameMap(HashMap<String,String> fontToFileMap,
                                HashMap<String,String> fontToFamilyNameMap,
                                HashMap<String,ArrayList<String>>
                                familyToFontListMap,
                                Locale locale) {
    }

    /* Obtained from Platform APIs (windows only)
     * Map from lower-case font full name to basename of font file.
     * Eg "arial bold" -> ARIALBD.TTF.
     * For TTC files, there is a mapping for each font in the file.
     */
    private HashMap<String,String> fontToFileMap = null;

    /* Obtained from Platform APIs (windows only)
     * Map from lower-case font full name to the name of its font family
     * Eg "arial bold" -> "Arial"
     */
    private HashMap<String,String> fontToFamilyNameMap = null;

    /* Obtained from Platform APIs (windows only)
     * Map from a lower-case family name to a list of full names of
     * the member fonts, eg:
     * "arial" -> ["Arial", "Arial Bold", "Arial Italic","Arial Bold Italic"]
     */
    private HashMap<String,ArrayList<String>> familyToFontListMap= null;

    /* The directories which contain platform fonts */
    private String[] pathDirs = null;

    private boolean haveCheckedUnreferencedFontFiles;

    private String[] getFontFilesFromPath(boolean noType1) {
        final FilenameFilter filter;
        if (noType1) {
            filter = ttFilter;
        } else {
            filter = new TTorT1Filter();
        }
        if (pathDirs.length == 1) {
            File dir = new File(pathDirs[0]);
            String[] files = dir.list(filter);
            if (files == null) {
                return new String[0];
            }
            for (int f=0; f<files.length; f++) {
                files[f] = files[f].toLowerCase();
            }
            return files;
        } else {
            ArrayList<String> fileList = new ArrayList<>();
            for (int i = 0; i< pathDirs.length; i++) {
                File dir = new File(pathDirs[i]);
                String[] files = dir.list(filter);
                if (files == null) {
                    continue;
                }
                for (int f = 0; f < files.length ; f++) {
                    fileList.add(files[f].toLowerCase());
                }
            }
            return fileList.toArray(STR_ARRAY);
        }
    }

    /* This is needed since some windows registry names don't match
     * the font names.
     * - UPC styled font names have a double space, but the
     * registry entry mapping to a file doesn't.
     * - Marlett is in a hidden file not listed in the registry
     * - The registry advertises that the file david.ttf contains a
     * font with the full name "David Regular" when in fact its
     * just "David".
     * Directly fix up these known cases as this is faster.
     * If a font which doesn't match these known cases has no file,
     * it may be a font that has been temporarily added to the known set
     * or it may be an installed font with a missing registry entry.
     * Installed fonts are those in the windows font directories.
     * Make a best effort attempt to locate these.
     * We obtain the list of TrueType fonts in these directories and
     * filter out all the font files we already know about from the registry.
     * What remains may be "bad" fonts, duplicate fonts, or perhaps the
     * missing font(s) we are looking for.
     * Open each of these files to find out.
     */
    private void resolveWindowsFonts() {

        ArrayList<String> unmappedFontNames = null;
        for (String font : fontToFamilyNameMap.keySet()) {
            String file = fontToFileMap.get(font);
            if (file == null) {
                if (font.indexOf("  ") > 0) {
                    String newName = font.replaceFirst("  ", " ");
                    file = fontToFileMap.get(newName);
                    /* If this name exists and isn't for a valid name
                     * replace the mapping to the file with this font
                     */
                    if (file != null &&
                        !fontToFamilyNameMap.containsKey(newName)) {
                        fontToFileMap.remove(newName);
                        fontToFileMap.put(font, file);
                    }
                } else if (font.equals("marlett")) {
                    fontToFileMap.put(font, "marlett.ttf");
                } else if (font.equals("david")) {
                    file = fontToFileMap.get("david regular");
                    if (file != null) {
                        fontToFileMap.remove("david regular");
                        fontToFileMap.put("david", file);
                    }
                } else {
                    if (unmappedFontNames == null) {
                        unmappedFontNames = new ArrayList<>();
                    }
                    unmappedFontNames.add(font);
                }
            }
        }

        if (unmappedFontNames != null) {
            HashSet<String> unmappedFontFiles = new HashSet<>();

            /* Every font key in fontToFileMap ought to correspond to a
             * font key in fontToFamilyNameMap. Entries that don't seem
             * to correspond are likely fonts that were named differently
             * by GDI than in the registry. One known cause of this is when
             * Windows has had its regional settings changed so that from
             * GDI we get a localised (eg Chinese or Japanese) name for the
             * font, but the registry retains the English version of the name
             * that corresponded to the "install" locale for windows.
             * Since we are in this code block because there are unmapped
             * font names, we can look to find unused font->file mappings
             * and then open the files to read the names. We don't generally
             * want to open font files, as its a performance hit, but this
             * occurs only for a small number of fonts on specific system
             * configs - ie is believed that a "true" Japanese windows would
             * have JA names in the registry too.
             * Clone fontToFileMap and remove from the clone all keys which
             * match a fontToFamilyNameMap key. What remains maps to the
             * files we want to open to find the fonts GDI returned.
             * A font in such a file is added to the fontToFileMap after
             * checking its one of the unmappedFontNames we are looking for.
             * The original name that didn't map is removed from fontToFileMap
             * so essentially this "fixes up" fontToFileMap to use the same
             * name as GDI.
             * Also note that typically the fonts for which this occurs in
             * CJK locales are TTC fonts and not all fonts in a TTC may have
             * localised names. Eg MSGOTHIC.TTC contains 3 fonts and one of
             * them "MS UI Gothic" has no JA name whereas the other two do.
             * So not every font in these files is unmapped or new.
             */
            @SuppressWarnings("unchecked")
            HashMap<String,String> ffmapCopy =
                (HashMap<String,String>)(fontToFileMap.clone());
            for (String key : fontToFamilyNameMap.keySet()) {
                ffmapCopy.remove(key);
            }
            for (String key : ffmapCopy.keySet()) {
                unmappedFontFiles.add(ffmapCopy.get(key));
                fontToFileMap.remove(key);
            }

            resolveFontFiles(unmappedFontFiles, unmappedFontNames);

            /* If there are still unmapped font names, this means there's
             * something that wasn't in the registry. We need to get all
             * the font files directly and look at the ones that weren't
             * found in the registry.
             */
            if (unmappedFontNames.size() > 0) {

                /* getFontFilesFromPath() returns all lower case names.
                 * To compare we also need lower case
                 * versions of the names from the registry.
                 */
                ArrayList<String> registryFiles = new ArrayList<>();

                for (String regFile : fontToFileMap.values()) {
                    registryFiles.add(regFile.toLowerCase());
                }
                /* We don't look for Type1 files here as windows will
                 * not enumerate these, so aren't useful in reconciling
                 * GDI's unmapped files. We do find these later when
                 * we enumerate all fonts.
                 */
                for (String pathFile : getFontFilesFromPath(true)) {
                    if (!registryFiles.contains(pathFile)) {
                        unmappedFontFiles.add(pathFile);
                    }
                }

                resolveFontFiles(unmappedFontFiles, unmappedFontNames);
            }

            /* remove from the set of names that will be returned to the
             * user any fonts that can't be mapped to files.
             */
            if (unmappedFontNames.size() > 0) {
                int sz = unmappedFontNames.size();
                for (int i=0; i<sz; i++) {
                    String name = unmappedFontNames.get(i);
                    String familyName = fontToFamilyNameMap.get(name);
                    if (familyName != null) {
                        ArrayList<String> family = familyToFontListMap.get(familyName);
                        if (family != null) {
                            if (family.size() <= 1) {
                                familyToFontListMap.remove(familyName);
                            }
                        }
                    }
                    fontToFamilyNameMap.remove(name);
                    if (FontUtilities.isLogging()) {
                        FontUtilities.logInfo("No file for font:" + name);
                    }
                }
            }
        }
    }

    /**
     * In some cases windows may have fonts in the fonts folder that
     * don't show up in the registry or in the GDI calls to enumerate fonts.
     * The only way to find these is to list the directory. We invoke this
     * only in getAllFonts/Families, so most searches for a specific
     * font that is satisfied by the GDI/registry calls don't take the
     * additional hit of listing the directory. This hit is small enough
     * that its not significant in these 'enumerate all the fonts' cases.
     * The basic approach is to cross-reference the files windows found
     * with the ones in the directory listing approach, and for each
     * in the latter list that is missing from the former list, register it.
     */
    private synchronized void checkForUnreferencedFontFiles() {
        if (haveCheckedUnreferencedFontFiles) {
            return;
        }
        haveCheckedUnreferencedFontFiles = true;
        if (!FontUtilities.isWindows) {
            return;
        }
        /* getFontFilesFromPath() returns all lower case names.
         * To compare we also need lower case
         * versions of the names from the registry.
         */
        ArrayList<String> registryFiles = new ArrayList<>();
        for (String regFile : fontToFileMap.values()) {
            registryFiles.add(regFile.toLowerCase());
        }

        /* To avoid any issues with concurrent modification, create
         * copies of the existing maps, add the new fonts into these
         * and then replace the references to the old ones with the
         * new maps. ConcurrentHashmap is another option but its a lot
         * more changes and with this exception, these maps are intended
         * to be static.
         */
        HashMap<String,String> fontToFileMap2 = null;
        HashMap<String,String> fontToFamilyNameMap2 = null;
        HashMap<String,ArrayList<String>> familyToFontListMap2 = null;

        for (String pathFile : getFontFilesFromPath(false)) {
            if (!registryFiles.contains(pathFile)) {
                if (FontUtilities.isLogging()) {
                    FontUtilities.logInfo("Found non-registry file : " + pathFile);
                }
                PhysicalFont f = registerFontFile(getPathName(pathFile));
                if (f == null) {
                    continue;
                }
                if (fontToFileMap2 == null) {
                    fontToFileMap2 = new HashMap<>(fontToFileMap);
                    fontToFamilyNameMap2 = new HashMap<>(fontToFamilyNameMap);
                    familyToFontListMap2 = new HashMap<>(familyToFontListMap);
                }
                String fontName = f.getFontName(null);
                String family = f.getFamilyName(null);
                String familyLC = family.toLowerCase();
                fontToFamilyNameMap2.put(fontName, family);
                fontToFileMap2.put(fontName, pathFile);
                ArrayList<String> fonts = familyToFontListMap2.get(familyLC);
                if (fonts == null) {
                    fonts = new ArrayList<>();
                } else {
                    fonts = new ArrayList<>(fonts);
                }
                fonts.add(fontName);
                familyToFontListMap2.put(familyLC, fonts);
            }
        }
        if (fontToFileMap2 != null) {
            fontToFileMap = fontToFileMap2;
            familyToFontListMap = familyToFontListMap2;
            fontToFamilyNameMap = fontToFamilyNameMap2;
        }
    }

    private void resolveFontFiles(HashSet<String> unmappedFiles,
                                  ArrayList<String> unmappedFonts) {

        Locale l = SunToolkit.getStartupLocale();

        for (String file : unmappedFiles) {
            try {
                int fn = 0;
                TrueTypeFont ttf;
                String fullPath = getPathName(file);
                if (FontUtilities.isLogging()) {
                    FontUtilities.logInfo("Trying to resolve file " + fullPath);
                }
                do {
                    ttf = new TrueTypeFont(fullPath, null, fn++, false);
                    //  prefer the font's locale name.
                    String fontName = ttf.getFontName(l).toLowerCase();
                    if (unmappedFonts.contains(fontName)) {
                        fontToFileMap.put(fontName, file);
                        unmappedFonts.remove(fontName);
                        if (FontUtilities.isLogging()) {
                            FontUtilities.logInfo("Resolved absent registry entry for " +
                                            fontName + " located in " + fullPath);
                        }
                    }
                }
                while (fn < ttf.getFontCount());
            } catch (Exception e) {
            }
        }
    }

    /* Hardwire the English names and expected file names of fonts
     * commonly used at start up. Avoiding until later even the small
     * cost of calling platform APIs to locate these can help.
     * The code that registers these fonts needs to "bail" if any
     * of the files do not exist, so it will verify the existence of
     * all non-null file names first.
     * They are added in to a map with nominally the first
     * word in the name of the family as the key. In all the cases
     * we are using the family name is a single word, and as is
     * more or less required the family name is the initial sequence
     * in a full name. So lookup first finds the matching description,
     * then registers the whole family, returning the right font.
     */
    public static class FamilyDescription {
        public String familyName;
        public String plainFullName;
        public String boldFullName;
        public String italicFullName;
        public String boldItalicFullName;
        public String plainFileName;
        public String boldFileName;
        public String italicFileName;
        public String boldItalicFileName;
        boolean failed;
    }

    static volatile HashMap<String, FamilyDescription> platformFontMap;

    /**
     * default implementation does nothing.
     */
    public HashMap<String, FamilyDescription> populateHardcodedFileNameMap() {
        return new HashMap<>(0);
    }

    Font2D findFontFromPlatformMap(String lcName, int style) {
        HashMap<String, FamilyDescription> platformFontMap = SunFontManager.platformFontMap;
        if (platformFontMap == null) {
            platformFontMap = populateHardcodedFileNameMap();
            SunFontManager.platformFontMap = platformFontMap;
        }

        if (platformFontMap == null || platformFontMap.size() == 0) {
            return null;
        }

        int spaceIndex = lcName.indexOf(' ');
        String firstWord = lcName;
        if (spaceIndex > 0) {
            firstWord = lcName.substring(0, spaceIndex);
        }

        FamilyDescription fd = platformFontMap.get(firstWord);
        if (fd == null || fd.failed) {
            return null;
        }
        /* Once we've established that its at least the first word,
         * we need to dig deeper to make sure its a match for either
         * a full name, or the family name, to make sure its not
         * a request for some other font that just happens to start
         * with the same first word.
         */
        int styleIndex = -1;
        if (lcName.equalsIgnoreCase(fd.plainFullName)) {
            styleIndex = 0;
        } else if (lcName.equalsIgnoreCase(fd.boldFullName)) {
            styleIndex = 1;
        } else if (lcName.equalsIgnoreCase(fd.italicFullName)) {
            styleIndex = 2;
        } else if (lcName.equalsIgnoreCase(fd.boldItalicFullName)) {
            styleIndex = 3;
        }
        if (styleIndex == -1 && !lcName.equalsIgnoreCase(fd.familyName)) {
            return null;
        }

        String plainFile = null, boldFile = null,
            italicFile = null, boldItalicFile = null;

        boolean failure = false;
        /* In a terminal server config, its possible that getPathName()
         * will return null, if the file doesn't exist, hence the null
         * checks on return. But in the normal client config we need to
         * follow this up with a check to see if all the files really
         * exist for the non-null paths.
         */
         getPlatformFontDirs(noType1Font);

        if (fd.plainFileName != null) {
            plainFile = getPathName(fd.plainFileName);
            if (plainFile == null) {
                failure = true;
            }
        }

        if (fd.boldFileName != null) {
            boldFile = getPathName(fd.boldFileName);
            if (boldFile == null) {
                failure = true;
            }
        }

        if (fd.italicFileName != null) {
            italicFile = getPathName(fd.italicFileName);
            if (italicFile == null) {
                failure = true;
            }
        }

        if (fd.boldItalicFileName != null) {
            boldItalicFile = getPathName(fd.boldItalicFileName);
            if (boldItalicFile == null) {
                failure = true;
            }
        }

        if (failure) {
            if (FontUtilities.isLogging()) {
                FontUtilities.logInfo("Hardcoded file missing looking for " + lcName);
            }
            fd.failed = true;
            return null;
        }

        /* Some of these may be null,as not all styles have to exist */
        final String[] files = {
            plainFile, boldFile, italicFile, boldItalicFile } ;

         for (int i=0; i<files.length; i++) {
             if (files[i] == null) {
                 continue;
             }
             File f = new File(files[i]);
             if (!f.exists()) {
                 failure = true;
                 break;
             }
         }

        if (failure) {
            if (FontUtilities.isLogging()) {
                FontUtilities.logInfo("Hardcoded file missing looking for " + lcName);
            }
            fd.failed = true;
            return null;
        }

        /* If we reach here we know that we have all the files we
         * expect, so all should be fine so long as the contents
         * are what we'd expect. Now on to registering the fonts.
         * Currently this code only looks for TrueType fonts, so format
         * and rank can be specified without looking at the filename.
         */
        Font2D font = null;
        for (int f=0;f<files.length;f++) {
            if (files[f] == null) {
                continue;
            }
            PhysicalFont pf =
                registerFontFile(files[f], null,
                                 FONTFORMAT_TRUETYPE, false, Font2D.TTF_RANK);
            if (f == styleIndex) {
                font = pf;
            }
        }


        /* Two general cases need a bit more work here.
         * 1) If font is null, then it was perhaps a request for a
         * non-existent font, such as "Tahoma Italic", or a family name -
         * where family and full name of the plain font differ.
         * Fall back to finding the closest one in the family.
         * This could still fail if a client specified "Segoe" instead of
         * "Segoe UI".
         * 2) The request is of the form "MyFont Bold", style=Font.ITALIC,
         * and so we want to see if there's a Bold Italic font, or
         * "MyFamily", style=Font.BOLD, and we may have matched the plain,
         * but now need to revise that to the BOLD font.
         */
        FontFamily fontFamily = FontFamily.getFamily(fd.familyName);
        if (fontFamily != null) {
            if (font == null) {
                font = fontFamily.getFont(style);
                if (font == null) {
                    font = fontFamily.getClosestStyle(style);
                }
            } else if (style > 0 && style != font.style) {
                style |= font.style;
                font = fontFamily.getFont(style);
                if (font == null) {
                    font = fontFamily.getClosestStyle(style);
                }
            }
        }

        return font;
    }
    private synchronized HashMap<String,String> getFullNameToFileMap() {
        if (fontToFileMap == null) {

            pathDirs = getPlatformFontDirs(noType1Font);

            fontToFileMap = new HashMap<>(100);
            fontToFamilyNameMap = new HashMap<>(100);
            familyToFontListMap = new HashMap<>(50);
            populateFontFileNameMap(fontToFileMap,
                                    fontToFamilyNameMap,
                                    familyToFontListMap,
                                    Locale.ENGLISH);
            if (FontUtilities.isWindows) {
                resolveWindowsFonts();
            }
            if (FontUtilities.isLogging()) {
                logPlatformFontInfo();
            }
        }
        return fontToFileMap;
    }

    private void logPlatformFontInfo() {
        PlatformLogger logger = FontUtilities.getLogger();
        for (int i=0; i< pathDirs.length;i++) {
            logger.info("fontdir="+pathDirs[i]);
        }
        for (String keyName : fontToFileMap.keySet()) {
            logger.info("font="+keyName+" file="+ fontToFileMap.get(keyName));
        }
        for (String keyName : fontToFamilyNameMap.keySet()) {
            logger.info("font="+keyName+" family="+
                        fontToFamilyNameMap.get(keyName));
        }
        for (String keyName : familyToFontListMap.keySet()) {
            logger.info("family="+keyName+ " fonts="+
                        familyToFontListMap.get(keyName));
        }
    }

    /* Note this return list excludes logical fonts and JRE fonts */
    protected String[] getFontNamesFromPlatform() {
        if (getFullNameToFileMap().size() == 0) {
            return null;
        }
        checkForUnreferencedFontFiles();
        /* This odd code with TreeMap is used to preserve a historical
         * behaviour wrt the sorting order .. */
        ArrayList<String> fontNames = new ArrayList<>();
        for (ArrayList<String> a : familyToFontListMap.values()) {
            for (String s : a) {
                fontNames.add(s);
            }
        }
        return fontNames.toArray(STR_ARRAY);
    }

    public boolean gotFontsFromPlatform() {
        return getFullNameToFileMap().size() != 0;
    }

    public String getFileNameForFontName(String fontName) {
        String fontNameLC = fontName.toLowerCase(Locale.ENGLISH);
        return fontToFileMap.get(fontNameLC);
    }

    private PhysicalFont registerFontFile(String file) {
        if (new File(file).isAbsolute() &&
            !registeredFonts.containsKey(file)) {
            int fontFormat = FONTFORMAT_NONE;
            int fontRank = Font2D.UNKNOWN_RANK;
            if (ttFilter.accept(null, file)) {
                fontFormat = FONTFORMAT_TRUETYPE;
                fontRank = Font2D.TTF_RANK;
            } else if
                (t1Filter.accept(null, file)) {
                fontFormat = FONTFORMAT_TYPE1;
                fontRank = Font2D.TYPE1_RANK;
            }
            if (fontFormat == FONTFORMAT_NONE) {
                return null;
            }
            return registerFontFile(file, null, fontFormat, false, fontRank);
        }
        return null;
    }

    /* Used to register any font files that are found by platform APIs
     * that weren't previously found in the standard font locations.
     * the isAbsolute() check is needed since that's what's stored in the
     * set, and on windows, the fonts in the system font directory that
     * are in the fontToFileMap are just basenames. We don't want to try
     * to register those again, but we do want to register other registry
     * installed fonts.
     */
    protected void registerOtherFontFiles(HashSet<String> registeredFontFiles) {
        if (getFullNameToFileMap().size() == 0) {
            return;
        }
        for (String file : fontToFileMap.values()) {
            registerFontFile(file);
        }
    }

    public boolean
        getFamilyNamesFromPlatform(TreeMap<String,String> familyNames,
                                   Locale requestedLocale) {
        if (getFullNameToFileMap().size() == 0) {
            return false;
        }
        checkForUnreferencedFontFiles();
        for (String name : fontToFamilyNameMap.values()) {
            familyNames.put(name.toLowerCase(requestedLocale), name);
        }
        return true;
    }

    /* Path may be absolute or a base file name relative to one of
     * the platform font directories
     */
    private String getPathName(final String s) {
        File f = new File(s);
        if (f.isAbsolute()) {
            return s;
        } else if (pathDirs.length==1) {
            return pathDirs[0] + File.separator + s;
        } else {
            for (int p = 0; p < pathDirs.length; p++) {
                f = new File(pathDirs[p] + File.separator + s);
                if (f.exists()) {
                    return f.getAbsolutePath();
                }
            }
        }
        return s; // shouldn't happen, but harmless
    }

    /* lcName is required to be lower case for use as a key.
     * lcName may be a full name, or a family name, and style may
     * be specified in addition to either of these. So be sure to
     * get the right one. Since an app *could* ask for "Foo Regular"
     * and later ask for "Foo Italic", if we don't register all the
     * styles, then logic in findFont2D may try to style the original
     * so we register the entire family if we get a match here.
     * This is still a big win because this code is invoked where
     * otherwise we would register all fonts.
     * It's also useful for the case where "Foo Bold" was specified with
     * style Font.ITALIC, as we would want in that case to try to return
     * "Foo Bold Italic" if it exists, and it is only by locating "Foo Bold"
     * and opening it that we really "know" it's Bold, and can look for
     * a font that supports that and the italic style.
     * The code in here is not overtly windows-specific but in fact it
     * is unlikely to be useful as is on other platforms. It is maintained
     * in this shared source file to be close to its sole client and
     * because so much of the logic is intertwined with the logic in
     * findFont2D.
     */
    private Font2D findFontFromPlatform(String lcName, int style) {
        if (getFullNameToFileMap().size() == 0) {
            return null;
        }

        ArrayList<String> family = null;
        String fontFile = null;
        String familyName = fontToFamilyNameMap.get(lcName);
        if (familyName != null) {
            fontFile = fontToFileMap.get(lcName);
            family = familyToFontListMap.get
                (familyName.toLowerCase(Locale.ENGLISH));
        } else {
            family = familyToFontListMap.get(lcName); // is lcName is a family?
            if (family != null && family.size() > 0) {
                String lcFontName = family.get(0).toLowerCase(Locale.ENGLISH);
                if (lcFontName != null) {
                    familyName = fontToFamilyNameMap.get(lcFontName);
                }
            }
        }
        if (family == null || familyName == null) {
            return null;
        }
        String [] fontList = family.toArray(STR_ARRAY);
        if (fontList.length == 0) {
            return null;
        }

        /* first check that for every font in this family we can find
         * a font file. The specific reason for doing this is that
         * in at least one case on Windows a font has the face name "David"
         * but the registry entry is "David Regular". That is the "unique"
         * name of the font but in other cases the registry contains the
         * "full" name. See the specifications of name ids 3 and 4 in the
         * TrueType 'name' table.
         * In general this could cause a problem that we fail to register
         * if we all members of a family that we may end up mapping to
         * the wrong font member: eg return Bold when Plain is needed.
         */
        for (int f=0;f<fontList.length;f++) {
            String fontNameLC = fontList[f].toLowerCase(Locale.ENGLISH);
            String fileName = fontToFileMap.get(fontNameLC);
            if (fileName == null) {
                if (FontUtilities.isLogging()) {
                    FontUtilities.logInfo("Platform lookup : No file for font " +
                                    fontList[f] + " in family " +familyName);
                }
                return null;
            }
        }

        /* Currently this code only looks for TrueType fonts, so format
         * and rank can be specified without looking at the filename.
         */
        PhysicalFont physicalFont = null;
        if (fontFile != null) {
            physicalFont = registerFontFile(getPathName(fontFile), null,
                                            FONTFORMAT_TRUETYPE, false,
                                            Font2D.TTF_RANK);
        }
        /* Register all fonts in this family. */
        for (int f=0;f<fontList.length;f++) {
            String fontNameLC = fontList[f].toLowerCase(Locale.ENGLISH);
            String fileName = fontToFileMap.get(fontNameLC);
            if (fontFile != null && fontFile.equals(fileName)) {
                continue;
            }
            /* Currently this code only looks for TrueType fonts, so format
             * and rank can be specified without looking at the filename.
             */
            registerFontFile(getPathName(fileName), null,
                             FONTFORMAT_TRUETYPE, false, Font2D.TTF_RANK);
        }

        Font2D font = null;
        FontFamily fontFamily = FontFamily.getFamily(familyName);
        /* Handle case where request "MyFont Bold", style=Font.ITALIC */
        if (physicalFont != null) {
            style |= physicalFont.style;
        }
        if (fontFamily != null) {
            font = fontFamily.getFont(style);
            if (font == null) {
                font = fontFamily.getClosestStyle(style);
            }
        }
        return font;
    }

    private ConcurrentHashMap<String, Font2D> fontNameCache =
        new ConcurrentHashMap<>();

    /*
     * The client supplies a name and a style.
     * The name could be a family name, or a full name.
     * A font may exist with the specified style, or it may
     * exist only in some other style. For non-native fonts the scaler
     * may be able to emulate the required style.
     */
    public Font2D findFont2D(String name, int style, int fallback) {
        if (name == null) return null;
        String lowerCaseName = name.toLowerCase(Locale.ENGLISH);
        String mapName = lowerCaseName + dotStyleStr(style);

        /* If preferLocaleFonts() or preferProportionalFonts() has been
         * called we may be using an alternate set of composite fonts in this
         * app context. The presence of a pre-built name map indicates whether
         * this is so, and gives access to the alternate composite for the
         * name.
         */
        Font2D font = fontNameCache.get(mapName);
        if (font != null) {
            return font;
        }
        if (FontUtilities.isLogging()) {
            FontUtilities.logInfo("Search for font: " + name);
        }

        // The check below is just so that the bitmap fonts being set by
        // AWT and Swing thru the desktop properties do not trigger the
        // the load fonts case. The two bitmap fonts are now mapped to
        // appropriate equivalents for serif and sansserif.
        // Note that the cost of this comparison is only for the first
        // call until the map is filled.
        if (FontUtilities.isWindows) {
            if (lowerCaseName.equals("ms sans serif")) {
                name = "sansserif";
            } else if (lowerCaseName.equals("ms serif")) {
                name = "serif";
            }
        }

        /* This isn't intended to support a client passing in the
         * string default, but if a client passes in null for the name
         * the java.awt.Font class internally substitutes this name.
         * So we need to recognise it here to prevent a loadFonts
         * on the unrecognised name. The only potential problem with
         * this is it would hide any real font called "default"!
         * But that seems like a potential problem we can ignore for now.
         */
        if (lowerCaseName.equals("default")) {
            name = "dialog";
        }

        /* First see if its a family name. */
        FontFamily family = FontFamily.getFamily(name);
        if (family != null) {
            font = family.getFontWithExactStyleMatch(style);
            if (font == null) {
                font = findDeferredFont(name, style);
            }
            if (font == null) {
                font = findFontFromPlatform(lowerCaseName, style);
            }
            if (font == null) {
                font = family.getFont(style);
            }
            if (font == null) {
                font = family.getClosestStyle(style);
            }
            if (font != null) {
                fontNameCache.put(mapName, font);
                return font;
            }
        }

        /* If it wasn't a family name, it should be a full name of
         * either a composite, or a physical font
         */
        font = fullNameToFont.get(lowerCaseName);
        if (font != null) {
            /* Check that the requested style matches the matched font's style.
             * But also match style automatically if the requested style is
             * "plain". This because the existing behaviour is that the fonts
             * listed via getAllFonts etc always list their style as PLAIN.
             * This does lead to non-commutative behaviours where you might
             * start with "Lucida Sans Regular" and ask for a BOLD version
             * and get "Lucida Sans DemiBold" but if you ask for the PLAIN
             * style of "Lucida Sans DemiBold" you get "Lucida Sans DemiBold".
             * This consistent however with what happens if you have a bold
             * version of a font and no plain version exists - alg. styling
             * doesn't "unbolden" the font.
             */
            if (font.style == style || style == Font.PLAIN) {
                fontNameCache.put(mapName, font);
                return font;
            } else {
                /* If it was a full name like "Lucida Sans Regular", but
                 * the style requested is "bold", then we want to see if
                 * there's the appropriate match against another font in
                 * that family before trying to load all fonts, or applying a
                 * algorithmic styling
                 */
                family = FontFamily.getFamily(font.getFamilyName(null));
                if (family != null) {
                    Font2D familyFont = family.getFont(style|font.style);
                    /* We exactly matched the requested style, use it! */
                    if (familyFont != null) {
                        fontNameCache.put(mapName, familyFont);
                        return familyFont;
                    } else {
                        /* This next call is designed to support the case
                         * where bold italic is requested, and if we must
                         * style, then base it on either bold or italic -
                         * not on plain!
                         */
                        familyFont = family.getClosestStyle(style|font.style);
                        if (familyFont != null) {
                            /* The next check is perhaps one
                             * that shouldn't be done. ie if we get this
                             * far we have probably as close a match as we
                             * are going to get. We could load all fonts to
                             * see if somehow some parts of the family are
                             * loaded but not all of it.
                             */
                            if (familyFont.canDoStyle(style|font.style)) {
                                fontNameCache.put(mapName, familyFont);
                                return familyFont;
                            }
                        }
                    }
                }
            }
        }

        if (FontUtilities.isWindows) {

            font = findFontFromPlatformMap(lowerCaseName, style);
            if (FontUtilities.isLogging()) {
                FontUtilities.logInfo("findFontFromPlatformMap returned " + font);
            }

            if (font != null) {
                fontNameCache.put(mapName, font);
                return font;
            }
            /* Don't want Windows to return a font from C:\Windows\Fonts
             * if someone has installed a font with the same name
             * in the JRE.
             */
            if (deferredFontFiles.size() > 0) {
                font = findJREDeferredFont(lowerCaseName, style);
                if (font != null) {
                    fontNameCache.put(mapName, font);
                    return font;
                }
            }
            font = findFontFromPlatform(lowerCaseName, style);
            if (font != null) {
                if (FontUtilities.isLogging()) {
                    FontUtilities.logInfo("Found font via platform API for request:\"" +
                                    name + "\":, style="+style+
                                    " found font: " + font);
                }
                fontNameCache.put(mapName, font);
                return font;
            }
        }

        /* If reach here and no match has been located, then if there are
         * uninitialised deferred fonts, load as many of those as needed
         * to find the deferred font. If none is found through that
         * search continue on.
         * There is possibly a minor issue when more than one
         * deferred font implements the same font face. Since deferred
         * fonts are only those in font configuration files, this is a
         * controlled situation, the known case being Solaris euro_fonts
         * versions of Arial, Times New Roman, Courier New. However
         * the larger font will transparently replace the smaller one
         *  - see addToFontList() - when it is needed by the composite font.
         */
        if (deferredFontFiles.size() > 0) {
            font = findDeferredFont(name, style);
            if (font != null) {
                fontNameCache.put(mapName, font);
                return font;
            }
        }

        /* We check for application registered fonts before
         * explicitly loading all fonts as if necessary the registration
         * code will have done so anyway. And we don't want to needlessly
         * load the actual files for all fonts.
         * Just as for installed fonts we check for family before fullname.
         * We do not add these fonts to fontNameCache for the
         * app context case which eliminates the overhead of a per context
         * cache for these.
         */

        if (fontsAreRegistered) {
            Hashtable<String, FontFamily> familyTable = createdByFamilyName;
            Hashtable<String, Font2D> nameTable = createdByFullName;

            family = familyTable.get(lowerCaseName);
            if (family != null) {
                font = family.getFontWithExactStyleMatch(style);
                if (font == null) {
                    font = family.getFont(style);
                }
                if (font == null) {
                    font = family.getClosestStyle(style);
                }
                if (font != null) {
                    if (fontsAreRegistered) {
                        fontNameCache.put(mapName, font);
                    }
                    return font;
                }
            }
            font = nameTable.get(lowerCaseName);
            if (font != null) {
                if (fontsAreRegistered) {
                    fontNameCache.put(mapName, font);
                }
                return font;
            }
        }

        /* If reach here and no match has been located, then if all fonts
         * are not yet loaded, do so, and then recurse.
         */
        if (!loadedAllFonts) {
            if (FontUtilities.isLogging()) {
                FontUtilities.logInfo("Load fonts looking for:" + name);
            }
            loadFonts();
            loadedAllFonts = true;
            return findFont2D(name, style, fallback);
        }

        if (!loadedAllFontFiles) {
            if (FontUtilities.isLogging()) {
                FontUtilities.logInfo("Load font files looking for:" + name);
            }
            loadFontFiles();
            loadedAllFontFiles = true;
            return findFont2D(name, style, fallback);
        }

        /* The primary name is the locale default - ie not US/English but
         * whatever is the default in this locale. This is the way it always
         * has been but may be surprising to some developers if "Arial Regular"
         * were hard-coded in their app and yet "Arial Regular" was not the
         * default name. Fortunately for them, as a consequence of the JDK
         * supporting returning names and family names for arbitrary locales,
         * we also need to support searching all localised names for a match.
         * But because this case of the name used to reference a font is not
         * the same as the default for this locale is rare, it makes sense to
         * search a much shorter list of default locale names and only go to
         * a longer list of names in the event that no match was found.
         * So add here code which searches localised names too.
         * As in 1.4.x this happens only after loading all fonts, which
         * is probably the right order.
         */
        if ((font = findFont2DAllLocales(name, style)) != null) {
            fontNameCache.put(mapName, font);
            return font;
        }

        /* Perhaps its a "compatibility" name - timesroman, helvetica,
         * or courier, which 1.0 apps used for logical fonts.
         * We look for these "late" after a loadFonts as we must not
         * hide real fonts of these names.
         * Map these appropriately:
         * On windows this means according to the rules specified by the
         * FontConfiguration : do it only for encoding==Cp1252
         *
         * REMIND: this is something we plan to remove.
         */
        if (FontUtilities.isWindows) {
            String compatName =
                getFontConfiguration().getFallbackFamilyName(name, null);
            if (compatName != null) {
                font = findFont2D(compatName, style, fallback);
                fontNameCache.put(mapName, font);
                return font;
            }
        } else if (lowerCaseName.equals("timesroman")) {
            font = findFont2D("serif", style, fallback);
            fontNameCache.put(mapName, font);
            return font;
        } else if (lowerCaseName.equals("helvetica")) {
            font = findFont2D("sansserif", style, fallback);
            fontNameCache.put(mapName, font);
            return font;
        } else if (lowerCaseName.equals("courier")) {
            font = findFont2D("monospaced", style, fallback);
            fontNameCache.put(mapName, font);
            return font;
        }
        if (FontUtilities.isLogging()) {
            FontUtilities.logInfo("No font found for:" + name);
        }

        switch (fallback) {
        case PHYSICAL_FALLBACK: return getDefaultPhysicalFont();
        case LOGICAL_FALLBACK: return getDefaultLogicalFont(style);
        default: return null;
        }
    }

    public int getNumFonts() {
        return physicalFonts.size()+maxCompFont;
    }

    private static boolean fontSupportsEncoding(Font font, String encoding) {
        return FontUtilities.getFont2D(font).supportsEncoding(encoding);
    }

    protected abstract String getFontPath(boolean noType1Fonts);

    Thread fileCloser = null;
    Vector<File> tmpFontFiles = null;

    private int createdFontCount = 0;

    public Font2D[] createFont2D(File fontFile, int fontFormat, boolean all,
                                 boolean isCopy)
    throws FontFormatException {

        List<Font2D> fList = new ArrayList<>();
        int cnt = 1;
        String fontFilePath = fontFile.getPath();
        FileFont font2D = null;
        final File fFile = fontFile;
        boolean weakRefs = false;
        int maxStrikes = 0;
        synchronized (this) {
            if (createdFontCount < maxSoftRefCnt) {
                createdFontCount++;
            } else {
                  weakRefs = true;
                      maxStrikes = 10;
            }
        }
        try {
            switch (fontFormat) {
            case Font.TRUETYPE_FONT:
                font2D = new TrueTypeFont(fontFilePath, null, 0, true);
                font2D.setUseWeakRefs(weakRefs, maxStrikes);
                fList.add(font2D);
                if (!all) {
                    break;
                }
                cnt = ((TrueTypeFont)font2D).getFontCount();
                int index = 1;
                while (index < cnt) {
                    font2D = new TrueTypeFont(fontFilePath, null, index++, true);
                    font2D.setUseWeakRefs(weakRefs, maxStrikes);
                    fList.add(font2D);
                }
                break;
            case Font.TYPE1_FONT:
                font2D = new Type1Font(fontFilePath, null, isCopy);
                font2D.setUseWeakRefs(weakRefs, maxStrikes);
                fList.add(font2D);
                break;
            default:
                throw new FontFormatException("Unrecognised Font Format");
            }
        } catch (FontFormatException e) {
            if (isCopy) {
                fFile.delete();
            }
            throw(e);
        }
        if (isCopy) {
            FileFont.setFileToRemove(fList, fontFile, cnt);
            synchronized (FontManager.class) {

                if (tmpFontFiles == null) {
                    tmpFontFiles = new Vector<File>();
                }
                tmpFontFiles.add(fontFile);

                if (fileCloser == null) {
                    final Runnable fileCloserRunnable = new Runnable() {
                        public void run() {
                            for (int i = 0;i < CHANNELPOOLSIZE; i++) {
                                if (fontFileCache[i] != null) {
                                    try {
                                        fontFileCache[i].close();
                                    } catch (Exception e) {
                                    }
                                }
                            }
                            if (tmpFontFiles != null) {
                                File[] files = new File[tmpFontFiles.size()];
                                files = tmpFontFiles.toArray(files);
                                for (int f=0; f<files.length;f++) {
                                    try {
                                        files[f].delete();
                                    } catch (Exception e) {
                                    }
                                }
                            }
                        }
                    };
                    ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
                    fileCloser = new Thread(rootTG, fileCloserRunnable,
                                            "FileCloser", 0, false);
                    fileCloser.setContextClassLoader(null);
                    Runtime.getRuntime().addShutdownHook(fileCloser);
                }
            }
        }
        return fList.toArray(new Font2D[0]);
    }

    /* remind: used in X11GraphicsEnvironment and called often enough
     * that we ought to obsolete this code
     */
    public synchronized String getFullNameByFileName(String fileName) {
        PhysicalFont[] physFonts = getPhysicalFonts();
        for (int i=0;i<physFonts.length;i++) {
            if (physFonts[i].platName.equals(fileName)) {
                return (physFonts[i].getFontName(null));
            }
        }
        return null;
    }

    /*
     * This is called when font is determined to be invalid/bad.
     * It designed to be called (for example) by the font scaler
     * when in processing a font file it is discovered to be incorrect.
     * This is different than the case where fonts are discovered to
     * be incorrect during initial verification, as such fonts are
     * never registered.
     * Handles to this font held are re-directed to a default font.
     * This default may not be an ideal substitute buts it better than
     * crashing This code assumes a PhysicalFont parameter as it doesn't
     * make sense for a Composite to be "bad".
     */
    public synchronized void deRegisterBadFont(Font2D font2D) {
        if (!(font2D instanceof PhysicalFont)) {
            /* We should never reach here, but just in case */
            return;
        } else {
            if (FontUtilities.isLogging()) {
                FontUtilities.logSevere("Deregister bad font: " + font2D);
            }
            replaceFont((PhysicalFont)font2D, getDefaultPhysicalFont());
        }
    }

    /*
     * This encapsulates all the work that needs to be done when a
     * Font2D is replaced by a different Font2D.
     */
    public synchronized void replaceFont(PhysicalFont oldFont,
                                         PhysicalFont newFont) {

        if (oldFont.handle.font2D != oldFont) {
            /* already done */
            return;
        }

        /* If we try to replace the font with itself, that won't work,
         * so pick any alternative physical font
         */
        if (oldFont == newFont) {
            if (FontUtilities.isLogging()) {
                FontUtilities.logSevere("Can't replace bad font with itself " + oldFont);
            }
            PhysicalFont[] physFonts = getPhysicalFonts();
            for (int i=0; i<physFonts.length;i++) {
                if (physFonts[i] != newFont) {
                    newFont = physFonts[i];
                    break;
                }
            }
            if (oldFont == newFont) {
                if (FontUtilities.isLogging()) {
                    FontUtilities.logSevere("This is bad. No good physicalFonts found.");
                }
                return;
            }
        }

        /* eliminate references to this font, so it won't be located
         * by future callers, and will be eligible for GC when all
         * references are removed
         */
        oldFont.handle.font2D = newFont;
        physicalFonts.remove(oldFont.fullName);
        fullNameToFont.remove(oldFont.fullName.toLowerCase(Locale.ENGLISH));
        FontFamily.remove(oldFont);
        if (localeFullNamesToFont != null) {
            Map.Entry<?, ?>[] mapEntries = localeFullNamesToFont.entrySet().
                toArray(new Map.Entry<?, ?>[0]);
            /* Should I be replacing these, or just I just remove
             * the names from the map?
             */
            for (int i=0; i<mapEntries.length;i++) {
                if (mapEntries[i].getValue() == oldFont) {
                    try {
                        @SuppressWarnings("unchecked")
                        Map.Entry<String, PhysicalFont> tmp = (Map.Entry<String, PhysicalFont>)mapEntries[i];
                        tmp.setValue(newFont);
                    } catch (Exception e) {
                        /* some maps don't support this operation.
                         * In this case just give up and remove the entry.
                         */
                        localeFullNamesToFont.remove(mapEntries[i].getKey());
                    }
                }
            }
        }

        for (int i=0; i<maxCompFont; i++) {
            /* Deferred initialization of composites shouldn't be
             * a problem for this case, since a font must have been
             * initialised to be discovered to be bad.
             * Some JRE composites on Solaris use two versions of the same
             * font. The replaced font isn't bad, just "smaller" so there's
             * no need to make the slot point to the new font.
             * Since composites have a direct reference to the Font2D (not
             * via a handle) making this substitution is not safe and could
             * cause an additional problem and so this substitution is
             * warranted only when a font is truly "bad" and could cause
             * a crash. So we now replace it only if its being substituted
             * with some font other than a fontconfig rank font
             * Since in practice a substitution will have the same rank
             * this may never happen, but the code is safer even if its
             * also now a no-op.
             * The only obvious "glitch" from this stems from the current
             * implementation that when asked for the number of glyphs in a
             * composite it lies and returns the number in slot 0 because
             * composite glyphs aren't contiguous. Since we live with that
             * we can live with the glitch that depending on how it was
             * initialised a composite may return different values for this.
             * Fixing the issues with composite glyph ids is tricky as
             * there are exclusion ranges and unlike other fonts even the
             * true "numGlyphs" isn't a contiguous range. Likely the only
             * solution is an API that returns an array of glyph ranges
             * which takes precedence over the existing API. That might
             * also need to address excluding ranges which represent a
             * code point supported by an earlier component.
             */
            if (newFont.getRank() > Font2D.FONT_CONFIG_RANK) {
                compFonts[i].replaceComponentFont(oldFont, newFont);
            }
        }
    }

    private synchronized void loadLocaleNames() {
        if (localeFullNamesToFont != null) {
            return;
        }
        localeFullNamesToFont = new HashMap<>();
        Font2D[] fonts = getRegisteredFonts();
        for (int i=0; i<fonts.length; i++) {
            if (fonts[i] instanceof TrueTypeFont) {
                TrueTypeFont ttf = (TrueTypeFont)fonts[i];
                String[] fullNames = ttf.getAllFullNames();
                for (int n=0; n<fullNames.length; n++) {
                    localeFullNamesToFont.put(fullNames[n], ttf);
                }
                FontFamily family = FontFamily.getFamily(ttf.familyName);
                if (family != null) {
                    FontFamily.addLocaleNames(family, ttf.getAllFamilyNames());
                }
            }
        }
    }

    /* This replicate the core logic of findFont2D but operates on
     * all the locale names. This hasn't been merged into findFont2D to
     * keep the logic simpler and reduce overhead, since this case is
     * almost never used. The main case in which it is called is when
     * a bogus font name is used and we need to check all possible names
     * before returning the default case.
     */
    private Font2D findFont2DAllLocales(String name, int style) {
        if (FontUtilities.isLogging()) {
            FontUtilities.logInfo("Searching localised font names for:" + name);
        }

        /* If reach here and no match has been located, then if we have
         * not yet built the map of localeFullNamesToFont for TT fonts, do so
         * now. This method must be called after all fonts have been loaded.
         */
        if (localeFullNamesToFont == null) {
            loadLocaleNames();
        }
        String lowerCaseName = name.toLowerCase();
        Font2D font = null;

        /* First see if its a family name. */
        FontFamily family = FontFamily.getLocaleFamily(lowerCaseName);
        if (family != null) {
          font = family.getFont(style);
          if (font == null) {
            font = family.getClosestStyle(style);
          }
          if (font != null) {
              return font;
          }
        }

        /* If it wasn't a family name, it should be a full name. */
        synchronized (this) {
            font = localeFullNamesToFont.get(name);
        }
        if (font != null) {
            if (font.style == style || style == Font.PLAIN) {
                return font;
            } else {
                family = FontFamily.getFamily(font.getFamilyName(null));
                if (family != null) {
                    Font2D familyFont = family.getFont(style);
                    /* We exactly matched the requested style, use it! */
                    if (familyFont != null) {
                        return familyFont;
                    } else {
                        familyFont = family.getClosestStyle(style);
                        if (familyFont != null) {
                            /* The next check is perhaps one
                             * that shouldn't be done. ie if we get this
                             * far we have probably as close a match as we
                             * are going to get. We could load all fonts to
                             * see if somehow some parts of the family are
                             * loaded but not all of it.
                             * This check is commented out for now.
                             */
                            if (!familyFont.canDoStyle(style)) {
                                familyFont = null;
                            }
                            return familyFont;
                        }
                    }
                }
            }
        }
        return font;
    }

    /* Supporting "alternate" composite fonts on 2D graphics objects
     * is accessed by the application by calling methods on the local
     * GraphicsEnvironment. The overall implementation is described
     * in one place, here, since otherwise the implementation is spread
     * around it may be difficult to track.
     * The methods below call into SunGraphicsEnvironment which creates a
     * new FontConfiguration instance. The FontConfiguration class,
     * and its platform sub-classes are updated to take parameters requesting
     * these behaviours. This is then used to create new composite font
     * instances. Since this calls the initCompositeFont method in
     * SunGraphicsEnvironment it performs the same initialization as is
     * performed normally. There may be some duplication of effort, but
     * that code is already written to be able to perform properly if called
     * to duplicate work. The main difference is that if we detect we are
     * running in an applet/browser/Java plugin environment these new fonts
     * are not placed in the "default" maps but into an AppContext instance.
     * The font lookup mechanism in java.awt.Font.getFont2D() is also updated
     * so that look-up for composite fonts will in that case always
     * do a lookup rather than returning a cached result.
     * This is inefficient but necessary else singleton java.awt.Font
     * instances would not retrieve the correct Font2D for the appcontext.
     * sun.font.FontManager.findFont2D is also updated to that it uses
     * a name map cache specific to that appcontext.
     *
     * Getting an AppContext is expensive, so there is a global variable
     * that records whether these methods have ever been called and can
     * avoid the expense for almost all applications. Once the correct
     * CompositeFont is associated with the Font, everything should work
     * through existing mechanisms.
     * A special case is that GraphicsEnvironment.getAllFonts() must
     * return an AppContext specific list.
     *
     * Calling the methods below is "heavyweight" but it is expected that
     * these methods will be called very rarely.
     *
     * If _usingAlternateComposites is true, we are not in an "applet"
     * environment and the (single) application has selected
     * an alternate composite font behaviour.
     *
     * - Printing: The implementation delegates logical fonts to an AWT
     * mechanism which cannot use these alternate configurations.
     * We can detect that alternate fonts are in use and back-off to 2D, but
     * that uses outlines. Much of this can be fixed with additional work
     * but that may have to wait. The results should be correct, just not
     * optimal.
     */
    private boolean _usingAlternateComposites = false;

    private static boolean gAltJAFont = false;
    private boolean gLocalePref = false;
    private boolean gPropPref = false;

    /* Its used by the FontMetrics caching code which in such
     * a case cannot retrieve a cached metrics solely on the basis of
     * the Font.equals() method since it needs to also check if the Font2D
     * is the same.
     * We also use non-standard composites for Swing native L&F fonts on
     * Windows. In that case the policy is that the metrics reported are
     * based solely on the physical font in the first slot which is the
     * visible java.awt.Font. So in that case the metrics cache which tests
     * the Font does what we want. In the near future when we expand the GTK
     * logical font definitions we may need to revisit this if GTK reports
     * combined metrics instead. For now though this test can be simple.
     */
    public boolean usingAlternateCompositeFonts() {
        return _usingAlternateComposites;
    }

    /* Modifies the behaviour of a subsequent call to preferLocaleFonts()
     * to use Mincho instead of Gothic for dialoginput in JA locales
     * on windows. Not needed on other platforms.
     */
    public synchronized void useAlternateFontforJALocales() {
        if (FontUtilities.isLogging()) {
            FontUtilities.logInfo("Entered useAlternateFontforJALocales().");
        }

        if (!FontUtilities.isWindows) {
            return;
        }
        gAltJAFont = true;
    }

    public boolean usingAlternateFontforJALocales() {
        return gAltJAFont;
    }

    public synchronized void preferLocaleFonts() {
        if (FontUtilities.isLogging()) {
            FontUtilities.logInfo("Entered preferLocaleFonts().");
        }

        /* Test if re-ordering will have any effect */
        if (!FontConfiguration.willReorderForStartupLocale()) {
            return;
        }
        if (gLocalePref == true) {
            return;
        }
        gLocalePref = true;
        createCompositeFonts(fontNameCache, gLocalePref, gPropPref);
        _usingAlternateComposites = true;
    }

    public synchronized void preferProportionalFonts() {
        if (FontUtilities.isLogging()) {
            FontUtilities.logInfo("Entered preferProportionalFonts().");
        }

        /* If no proportional fonts are configured, there's no need
         * to take any action.
         */
        if (!FontConfiguration.hasMonoToPropMap()) {
            return;
        }
        if (gPropPref == true) {
            return;
        }
        gPropPref = true;
        createCompositeFonts(fontNameCache, gLocalePref, gPropPref);
        _usingAlternateComposites = true;
    }

    private static HashSet<String> installedNames = null;
    private static HashSet<String> getInstalledNames() {
        if (installedNames == null) {
           Locale l = getSystemStartupLocale();
           SunFontManager fontManager = SunFontManager.getInstance();
           String[] installedFamilies =
               fontManager.getInstalledFontFamilyNames(l);
           Font[] installedFonts = fontManager.getAllInstalledFonts();
           HashSet<String> names = new HashSet<>();
           for (int i=0; i<installedFamilies.length; i++) {
               names.add(installedFamilies[i].toLowerCase(l));
           }
           for (int i=0; i<installedFonts.length; i++) {
               names.add(installedFonts[i].getFontName(l).toLowerCase(l));
           }
           installedNames = names;
        }
        return installedNames;
    }

    private static final Object regFamilyLock  = new Object();
    private Hashtable<String,FontFamily> createdByFamilyName;
    private Hashtable<String,Font2D>     createdByFullName;
    private boolean fontsAreRegistered = false;

    public boolean registerFont(Font font) {
        /* This method should not be called with "null".
         * It is the caller's responsibility to ensure that.
         */
        if (font == null) {
            return false;
        }

        /* Initialise these objects only once we start to use this API */
        synchronized (regFamilyLock) {
            if (createdByFamilyName == null) {
                createdByFamilyName = new Hashtable<String,FontFamily>();
                createdByFullName = new Hashtable<String,Font2D>();
            }
        }

        if (! FontAccess.getFontAccess().isCreatedFont(font)) {
            return false;
        }
        /* We want to ensure that this font cannot override existing
         * installed fonts. Check these conditions :
         * - family name is not that of an installed font
         * - full name is not that of an installed font
         * - family name is not the same as the full name of an installed font
         * - full name is not the same as the family name of an installed font
         * The last two of these may initially look odd but the reason is
         * that (unfortunately) Font constructors do not distinuguish these.
         * An extreme example of such a problem would be a font which has
         * family name "Dialog.Plain" and full name of "Dialog".
         * The one arguably overly stringent restriction here is that if an
         * application wants to supply a new member of an existing family
         * It will get rejected. But since the JRE can perform synthetic
         * styling in many cases its not necessary.
         * We don't apply the same logic to registered fonts. If apps want
         * to do this lets assume they have a reason. It won't cause problems
         * except for themselves.
         */
        HashSet<String> names = getInstalledNames();
        Locale l = getSystemStartupLocale();
        String familyName = font.getFamily(l).toLowerCase();
        String fullName = font.getFontName(l).toLowerCase();
        if (names.contains(familyName) || names.contains(fullName)) {
            return false;
        }

        /* Checks passed, now register the font */
        Hashtable<String, FontFamily> familyTable = createdByFamilyName;
        Hashtable<String, Font2D> fullNameTable = createdByFullName;
        fontsAreRegistered = true;

        /* Create the FontFamily and add font to the tables */
        Font2D font2D = FontUtilities.getFont2D(font);
        int style = font2D.getStyle();
        FontFamily family = familyTable.get(familyName);
        if (family == null) {
            family = new FontFamily(font.getFamily(l));
            familyTable.put(familyName, family);
        }
        /* Remove name cache entries if not using app contexts.
         * To accommodate a case where code may have registered first a plain
         * family member and then used it and is now registering a bold family
         * member, we need to remove all members of the family, so that the
         * new style can get picked up rather than continuing to synthesise.
         */
        if (fontsAreRegistered) {
            removeFromCache(family.getFont(Font.PLAIN));
            removeFromCache(family.getFont(Font.BOLD));
            removeFromCache(family.getFont(Font.ITALIC));
            removeFromCache(family.getFont(Font.BOLD|Font.ITALIC));
            removeFromCache(fullNameTable.get(fullName));
        }
        family.setFont(font2D, style);
        fullNameTable.put(fullName, font2D);
        return true;
    }

    /* Remove from the name cache all references to the Font2D */
    private void removeFromCache(Font2D font) {
        if (font == null) {
            return;
        }
        String[] keys = fontNameCache.keySet().toArray(STR_ARRAY);
        for (int k=0; k<keys.length;k++) {
            if (fontNameCache.get(keys[k]) == font) {
                fontNameCache.remove(keys[k]);
            }
        }
    }

    // It may look odd to use TreeMap but its more convenient to the caller.
    public TreeMap<String, String> getCreatedFontFamilyNames() {

        Hashtable<String,FontFamily> familyTable;
        if (fontsAreRegistered) {
            familyTable = createdByFamilyName;
        } else {
            return null;
        }

        Locale l = getSystemStartupLocale();
        synchronized (familyTable) {
            TreeMap<String, String> map = new TreeMap<String, String>();
            for (FontFamily f : familyTable.values()) {
                Font2D font2D = f.getFont(Font.PLAIN);
                if (font2D == null) {
                    font2D = f.getClosestStyle(Font.PLAIN);
                }
                String name = font2D.getFamilyName(l);
                map.put(name.toLowerCase(l), name);
            }
            return map;
        }
    }

    public Font[] getCreatedFonts() {

        Hashtable<String,Font2D> nameTable;
        if (fontsAreRegistered) {
            nameTable = createdByFullName;
        } else {
            return null;
        }

        Locale l = getSystemStartupLocale();
        synchronized (nameTable) {
            Font[] fonts = new Font[nameTable.size()];
            int i=0;
            for (Font2D font2D : nameTable.values()) {
                fonts[i++] = new Font(font2D.getFontName(l), Font.PLAIN, 1);
            }
            return fonts;
        }
    }


    protected String[] getPlatformFontDirs(boolean noType1Fonts) {

        /* First check if we already initialised path dirs */
        if (pathDirs != null) {
            return pathDirs;
        }

        String path = getPlatformFontPath(noType1Fonts);
        StringTokenizer parser =
            new StringTokenizer(path, File.pathSeparator);
        ArrayList<String> pathList = new ArrayList<>();
        try {
            while (parser.hasMoreTokens()) {
                pathList.add(parser.nextToken());
            }
        } catch (NoSuchElementException e) {
        }
        pathDirs = pathList.toArray(new String[0]);
        return pathDirs;
    }

    /**
     * Returns an array of two strings. The first element is the
     * name of the font. The second element is the file name.
     */
    protected abstract String[] getDefaultPlatformFont();

    // Begin: Refactored from SunGraphicsEnvironment.

    /*
     * helper function for registerFonts
     */
    private void addDirFonts(String dirName, File dirFile,
                             FilenameFilter filter,
                             int fontFormat, boolean useJavaRasterizer,
                             int fontRank,
                             boolean defer, boolean resolveSymLinks) {
        String[] ls = dirFile.list(filter);
        if (ls == null || ls.length == 0) {
            return;
        }
        String[] fontNames = new String[ls.length];
        String[][] nativeNames = new String[ls.length][];
        int fontCount = 0;

        for (int i=0; i < ls.length; i++ ) {
            File theFile = new File(dirFile, ls[i]);
            String fullName = null;
            if (resolveSymLinks) {
                try {
                    fullName = theFile.getCanonicalPath();
                } catch (IOException e) {
                }
            }
            if (fullName == null) {
                fullName = dirName + File.separator + ls[i];
            }

            // REMIND: case compare depends on platform
            if (registeredFontFiles.contains(fullName)) {
                continue;
            }

            if (badFonts != null && badFonts.contains(fullName)) {
                if (FontUtilities.debugFonts()) {
                    FontUtilities.logWarning("skip bad font " + fullName);
                }
                continue; // skip this font file.
            }

            registeredFontFiles.add(fullName);

            if (FontUtilities.debugFonts()
                && FontUtilities.getLogger().isLoggable(PlatformLogger.Level.INFO)) {
                String message = "Registering font " + fullName;
                String[] natNames = getNativeNames(fullName, null);
                if (natNames == null) {
                    message += " with no native name";
                } else {
                    message += " with native name(s) " + natNames[0];
                    for (int nn = 1; nn < natNames.length; nn++) {
                        message += ", " + natNames[nn];
                    }
                }
                FontUtilities.logInfo(message);
            }
            fontNames[fontCount] = fullName;
            nativeNames[fontCount++] = getNativeNames(fullName, null);
        }
        registerFonts(fontNames, nativeNames, fontCount, fontFormat,
                         useJavaRasterizer, fontRank, defer);
        return;
    }

    protected String[] getNativeNames(String fontFileName,
                                      String platformName) {
        return null;
    }

    /**
     * Returns a file name for the physical font represented by this platform
     * font name. The default implementation tries to obtain the file name
     * from the font configuration.
     * Subclasses may override to provide information from other sources.
     */
    protected String getFileNameFromPlatformName(String platformFontName) {
        return fontConfig.getFileNameFromPlatformName(platformFontName);
    }

    /**
     * Return the default font configuration.
     */
    public FontConfiguration getFontConfiguration() {
        return fontConfig;
    }

    /* A call to this method should be followed by a call to
     * registerFontDirs(..)
     */
    public String getPlatformFontPath(boolean noType1Font) {
        if (fontPath == null) {
            fontPath = getFontPath(noType1Font);
        }
        return fontPath;
    }

    protected void loadFonts() {
        if (discoveredAllFonts) {
            return;
        }
        /* Use lock specific to the font system */
        synchronized (this) {
            if (FontUtilities.debugFonts()) {
                Thread.dumpStack();
                FontUtilities.logInfo("SunGraphicsEnvironment.loadFonts() called");
            }
            initialiseDeferredFonts();

            if (fontPath == null) {
                fontPath = getPlatformFontPath(noType1Font);
                registerFontDirs(fontPath);
            }
            if (fontPath != null) {
                // this will find all fonts including those already
                // registered. But we have checks in place to prevent
                // double registration.
                if (! gotFontsFromPlatform()) {
                    registerFontsOnPath(fontPath, false,
                                        Font2D.UNKNOWN_RANK,
                                        false, true);
                    loadedAllFontFiles = true;
                }
            }
            registerOtherFontFiles(registeredFontFiles);
            discoveredAllFonts = true;
        }
    }

    protected void registerFontDirs(String pathName) {
        return;
    }

    private void registerFontsOnPath(String pathName,
                                     boolean useJavaRasterizer, int fontRank,
                                     boolean defer, boolean resolveSymLinks) {

        StringTokenizer parser = new StringTokenizer(pathName,
                File.pathSeparator);
        try {
            while (parser.hasMoreTokens()) {
                registerFontsInDir(parser.nextToken(),
                        useJavaRasterizer, fontRank,
                        defer, resolveSymLinks);
            }
        } catch (NoSuchElementException e) {
        }
    }

    /* Called to register fall back fonts */
    public void registerFontsInDir(String dirName) {
        registerFontsInDir(dirName, true, Font2D.JRE_RANK, true, false);
    }

    // MACOSX begin -- need to access this in subclass
    protected void registerFontsInDir(String dirName, boolean useJavaRasterizer,
    // MACOSX end
                                    int fontRank,
                                    boolean defer, boolean resolveSymLinks) {
        File pathFile = new File(dirName);
        addDirFonts(dirName, pathFile, ttFilter,
                    FONTFORMAT_TRUETYPE, useJavaRasterizer,
                    fontRank==Font2D.UNKNOWN_RANK ?
                    Font2D.TTF_RANK : fontRank,
                    defer, resolveSymLinks);
        addDirFonts(dirName, pathFile, t1Filter,
                    FONTFORMAT_TYPE1, useJavaRasterizer,
                    fontRank==Font2D.UNKNOWN_RANK ?
                    Font2D.TYPE1_RANK : fontRank,
                    defer, resolveSymLinks);
    }

    protected void registerFontDir(String path) {
    }

    /**
     * Returns file name for default font, either absolute
     * or relative as needed by registerFontFile.
     */
    public synchronized String getDefaultFontFile() {
        return defaultFontFileName;
    }

    /**
     * Whether registerFontFile expects absolute or relative
     * font file names.
     */
    protected boolean useAbsoluteFontFileNames() {
        return true;
    }

    /**
     * Creates this environment's FontConfiguration.
     */
    protected abstract FontConfiguration createFontConfiguration();

    public abstract FontConfiguration
    createFontConfiguration(boolean preferLocaleFonts,
                            boolean preferPropFonts);

    /**
     * Returns face name for default font, or null if
     * no face names are used for CompositeFontDescriptors
     * for this platform.
     */
    public synchronized String getDefaultFontFaceName() {
        return defaultFontName;
    }

    public void loadFontFiles() {
        loadFonts();
        if (loadedAllFontFiles) {
            return;
        }
        /* Use lock specific to the font system */
        synchronized (this) {
            if (FontUtilities.debugFonts()) {
                Thread.dumpStack();
                FontUtilities.logInfo("loadAllFontFiles() called");
            }
            if (fontPath == null) {
                fontPath = getPlatformFontPath(noType1Font);
            }
            if (fontPath != null) {
                // this will find all fonts including those already
                // registered. But we have checks in place to prevent
                // double registration.
                registerFontsOnPath(fontPath, false,
                                    Font2D.UNKNOWN_RANK,
                                    false, true);
            }
            loadedAllFontFiles = true;
        }
    }

    /*
     * This method asks the font configuration API for all platform names
     * used as components of composite/logical fonts and iterates over these
     * looking up their corresponding file name and registers these fonts.
     * It also ensures that the fonts are accessible via platform APIs.
     * The composites themselves are then registered.
     */
    private void
        initCompositeFonts(FontConfiguration fontConfig,
                           ConcurrentHashMap<String, Font2D>  altNameCache) {
        if (FontUtilities.isLogging()) {
            FontUtilities.logInfo("Initialising composite fonts");
        }

        int numCoreFonts = fontConfig.getNumberCoreFonts();
        String[] fcFonts = fontConfig.getPlatformFontNames();
        for (int f=0; f<fcFonts.length; f++) {
            String platformFontName = fcFonts[f];
            String fontFileName =
                getFileNameFromPlatformName(platformFontName);
            String[] nativeNames = null;
            if (fontFileName == null
                || fontFileName.equals(platformFontName)) {
                /* No file located, so register using the platform name,
                 * i.e. as a native font.
                 */
                fontFileName = platformFontName;
            } else {
                if (f < numCoreFonts) {
                    /* If platform APIs also need to access the font, add it
                     * to a set to be registered with the platform too.
                     * This may be used to add the parent directory to the X11
                     * font path if its not already there. See the docs for the
                     * subclass implementation.
                     * This is now mainly for the benefit of X11-based AWT
                     * But for historical reasons, 2D initialisation code
                     * makes these calls.
                     * If the fontconfiguration file is properly set up
                     * so that all fonts are mapped to files and all their
                     * appropriate directories are specified, then this
                     * method will be low cost as it will return after
                     * a test that finds a null lookup map.
                     */
                    addFontToPlatformFontPath(platformFontName);
                }
                nativeNames = getNativeNames(fontFileName, platformFontName);
            }
            /* Uncomment these two lines to "generate" the XLFD->filename
             * mappings needed to speed start-up on Solaris.
             * Augment this with the appendedpathname and the mappings
             * for native (F3) fonts
             */
            //String platName = platformFontName.replaceAll(" ", "_");
            //System.out.println("filename."+platName+"="+fontFileName);
            registerFontFile(fontFileName, nativeNames,
                             Font2D.FONT_CONFIG_RANK, true);


        }
        /* This registers accumulated paths from the calls to
         * addFontToPlatformFontPath(..) and any specified by
         * the font configuration. Rather than registering
         * the fonts it puts them in a place and form suitable for
         * the Toolkit to pick up and use if a toolkit is initialised,
         * and if it uses X11 fonts.
         */
        registerPlatformFontsUsedByFontConfiguration();

        CompositeFontDescriptor[] compositeFontInfo
                = fontConfig.get2DCompositeFontInfo();
        for (int i = 0; i < compositeFontInfo.length; i++) {
            CompositeFontDescriptor descriptor = compositeFontInfo[i];
            String[] componentFileNames = descriptor.getComponentFileNames();
            String[] componentFaceNames = descriptor.getComponentFaceNames();

            /* It would be better eventually to handle this in the
             * FontConfiguration code which should also remove duplicate slots
             */
            if (missingFontFiles != null) {
                for (int ii=0; ii<componentFileNames.length; ii++) {
                    if (missingFontFiles.contains(componentFileNames[ii])) {
                        componentFileNames[ii] = getDefaultFontFile();
                        componentFaceNames[ii] = getDefaultFontFaceName();
                    }
                }
            }

            /* FontConfiguration needs to convey how many fonts it has added
             * as fallback component fonts which should not affect metrics.
             * The core component count will be the number of metrics slots.
             * This does not preclude other mechanisms for adding
             * fall back component fonts to the composite.
             */
            if (altNameCache != null) {
                SunFontManager.registerCompositeFont(
                    descriptor.getFaceName(),
                    componentFileNames, componentFaceNames,
                    descriptor.getCoreComponentCount(),
                    descriptor.getExclusionRanges(),
                    descriptor.getExclusionRangeLimits(),
                    true,
                    altNameCache);
            } else {
                registerCompositeFont(descriptor.getFaceName(),
                                      componentFileNames, componentFaceNames,
                                      descriptor.getCoreComponentCount(),
                                      descriptor.getExclusionRanges(),
                                      descriptor.getExclusionRangeLimits(),
                                      true);
            }
            if (FontUtilities.debugFonts()) {
                FontUtilities.logInfo("registered " + descriptor.getFaceName());
            }
        }
    }

    /**
     * Notifies graphics environment that the logical font configuration
     * uses the given platform font name. The graphics environment may
     * use this for platform specific initialization.
     */
    protected void addFontToPlatformFontPath(String platformFontName) {
    }

    protected void registerFontFile(String fontFileName, String[] nativeNames,
                                    int fontRank, boolean defer) {
//      REMIND: case compare depends on platform
        if (registeredFontFiles.contains(fontFileName)) {
            return;
        }
        int fontFormat;
        if (ttFilter.accept(null, fontFileName)) {
            fontFormat = FONTFORMAT_TRUETYPE;
        } else if (t1Filter.accept(null, fontFileName)) {
            fontFormat = FONTFORMAT_TYPE1;
        } else {
            fontFormat = FONTFORMAT_NATIVE;
        }
        registeredFontFiles.add(fontFileName);
        if (defer) {
            registerDeferredFont(fontFileName, fontFileName, nativeNames,
                                 fontFormat, false, fontRank);
        } else {
            registerFontFile(fontFileName, nativeNames, fontFormat, false,
                             fontRank);
        }
    }

    protected void registerPlatformFontsUsedByFontConfiguration() {
    }

    /*
     * A GE may verify whether a font file used in a fontconfiguration
     * exists. If it doesn't then either we may substitute the default
     * font, or perhaps elide it altogether from the composite font.
     * This makes some sense on windows where the font file is only
     * likely to be in one place. But on other OSes, eg Linux, the file
     * can move around depending. So there we probably don't want to assume
     * its missing and so won't add it to this list.
     * If this list - missingFontFiles - is non-null then the composite
     * font initialisation logic tests to see if a font file is in that
     * set.
     * Only one thread should be able to add to this set so we don't
     * synchronize.
     */
    protected void addToMissingFontFileList(String fileName) {
        if (missingFontFiles == null) {
            missingFontFiles = new HashSet<>();
        }
        missingFontFiles.add(fileName);
    }

    /*
     * This is for use only within getAllFonts().
     * Fonts listed in the fontconfig files for windows were all
     * on the "deferred" initialisation list. They were registered
     * either in the course of the application, or in the call to
     * loadFonts() within getAllFonts(). The fontconfig file specifies
     * the names of the fonts using the English names. If there's a
     * different name in the execution locale, then the platform will
     * report that, and we will construct the font with both names, and
     * thereby enumerate it twice. This happens for Japanese fonts listed
     * in the windows fontconfig, when run in the JA locale. The solution
     * is to rely (in this case) on the platform's font->file mapping to
     * determine that this name corresponds to a file we already registered.
     * This works because
     * - we know when we get here all deferred fonts are already initialised
     * - when we register a font file, we register all fonts in it.
     * - we know the fontconfig fonts are all in the windows registry
     */
    private boolean isNameForRegisteredFile(String fontName) {
        String fileName = getFileNameForFontName(fontName);
        if (fileName == null) {
            return false;
        }
        return registeredFontFiles.contains(fileName);
    }

    /*
     * This invocation is not in a privileged block because
     * all privileged operations (reading files and properties)
     * was conducted on the creation of the GE
     */
    public void
        createCompositeFonts(ConcurrentHashMap<String, Font2D> altNameCache,
                             boolean preferLocale,
                             boolean preferProportional) {

        FontConfiguration fontConfig =
            createFontConfiguration(preferLocale, preferProportional);
        initCompositeFonts(fontConfig, altNameCache);
    }

    /**
     * Returns all fonts installed in this environment.
     */
    public Font[] getAllInstalledFonts() {
        if (allFonts == null) {
            loadFonts();
            TreeMap<String, Font2D> fontMapNames = new TreeMap<>();
            /* warning: the number of composite fonts could change dynamically
             * if applications are allowed to create them. "allfonts" could
             * then be stale.
             */
            Font2D[] allfonts = getRegisteredFonts();
            for (int i=0; i < allfonts.length; i++) {
                if (!(allfonts[i] instanceof NativeFont)) {
                    fontMapNames.put(allfonts[i].getFontName(null),
                                     allfonts[i]);
                }
            }

            String[] platformNames = getFontNamesFromPlatform();
            if (platformNames != null) {
                for (int i=0; i<platformNames.length; i++) {
                    if (!isNameForRegisteredFile(platformNames[i])) {
                        fontMapNames.put(platformNames[i], null);
                    }
                }
            }

            String[] fontNames = fontMapNames.keySet().toArray(new String[0]);
            Font[] fonts = new Font[fontNames.length];
            for (int i=0; i < fontNames.length; i++) {
                fonts[i] = new Font(fontNames[i], Font.PLAIN, 1);
                Font2D f2d = fontMapNames.get(fontNames[i]);
                if (f2d  != null) {
                    FontAccess.getFontAccess().setFont2D(fonts[i], f2d.handle);
                }
            }
            allFonts = fonts;
        }

        Font []copyFonts = new Font[allFonts.length];
        System.arraycopy(allFonts, 0, copyFonts, 0, allFonts.length);
        return copyFonts;
    }

    /**
     * Get a list of installed fonts in the requested {@link Locale}.
     * The list contains the fonts Family Names.
     * If Locale is null, the default locale is used.
     *
     * @param requestedLocale, if null the default locale is used.
     * @return list of installed fonts in the system.
     */
    public String[] getInstalledFontFamilyNames(Locale requestedLocale) {
        if (requestedLocale == null) {
            requestedLocale = Locale.getDefault();
        }
        if (allFamilies != null && lastDefaultLocale != null &&
            requestedLocale.equals(lastDefaultLocale)) {
                String[] copyFamilies = new String[allFamilies.length];
                System.arraycopy(allFamilies, 0, copyFamilies,
                                 0, allFamilies.length);
                return copyFamilies;
        }

        TreeMap<String,String> familyNames = new TreeMap<String,String>();
        //  these names are always there and aren't localised
        String str;
        str = Font.SERIF;         familyNames.put(str.toLowerCase(), str);
        str = Font.SANS_SERIF;    familyNames.put(str.toLowerCase(), str);
        str = Font.MONOSPACED;    familyNames.put(str.toLowerCase(), str);
        str = Font.DIALOG;        familyNames.put(str.toLowerCase(), str);
        str = Font.DIALOG_INPUT;  familyNames.put(str.toLowerCase(), str);

        /* Platform APIs may be used to get the set of available family
         * names for the current default locale so long as it is the same
         * as the start-up system locale, rather than loading all fonts.
         */
        if (requestedLocale.equals(getSystemStartupLocale()) &&
            getFamilyNamesFromPlatform(familyNames, requestedLocale)) {
            /* Augment platform names with JRE font family names */
            getJREFontFamilyNames(familyNames, requestedLocale);
        } else {
            loadFontFiles();
            Font2D[] physicalfonts = getPhysicalFonts();
            for (int i=0; i < physicalfonts.length; i++) {
                if (!(physicalfonts[i] instanceof NativeFont)) {
                    String name =
                        physicalfonts[i].getFamilyName(requestedLocale);
                    familyNames.put(name.toLowerCase(requestedLocale), name);
                }
            }
        }

        // Add any native font family names here
        addNativeFontFamilyNames(familyNames, requestedLocale);

        String[] retval = familyNames.values().toArray(new String[0]);
        if (requestedLocale.equals(Locale.getDefault())) {
            lastDefaultLocale = requestedLocale;
            allFamilies = new String[retval.length];
            System.arraycopy(retval, 0, allFamilies, 0, allFamilies.length);
        }
        return retval;
    }

    // Provides an aperture to add native font family names to the map
    protected void addNativeFontFamilyNames(TreeMap<String, String> familyNames, Locale requestedLocale) { }

    public void register1dot0Fonts() {
        String type1Dir = "/usr/openwin/lib/X11/fonts/Type1";
        registerFontsInDir(type1Dir, true, Font2D.TYPE1_RANK, false, false);
    }

    /* Really we need only the JRE fonts family names, but there's little
     * overhead in doing this the easy way by adding all the currently
     * known fonts.
     */
    protected void getJREFontFamilyNames(TreeMap<String,String> familyNames,
                                         Locale requestedLocale) {
        registerDeferredJREFonts(jreFontDirName);
        Font2D[] physicalfonts = getPhysicalFonts();
        for (int i=0; i < physicalfonts.length; i++) {
            if (!(physicalfonts[i] instanceof NativeFont)) {
                String name =
                    physicalfonts[i].getFamilyName(requestedLocale);
                familyNames.put(name.toLowerCase(requestedLocale), name);
            }
        }
    }

    /**
     * Default locale can be changed but we need to know the initial locale
     * as that is what is used by native code. Changing Java default locale
     * doesn't affect that.
     * Returns the locale in use when using native code to communicate
     * with platform APIs. On windows this is known as the "system" locale,
     * and it is usually the same as the platform locale, but not always,
     * so this method also checks an implementation property used only
     * on windows and uses that if set.
     */
    private static Locale systemLocale = null;
    private static Locale getSystemStartupLocale() {
        if (systemLocale == null) {
            /* On windows the system locale may be different than the
             * user locale. This is an unsupported configuration, but
             * in that case we want to return a dummy locale that will
             * never cause a match in the usage of this API. This is
             * important because Windows documents that the family
             * names of fonts are enumerated using the language of
             * the system locale. BY returning a dummy locale in that
             * case we do not use the platform API which would not
             * return us the names we want.
             */
            String fileEncoding = System.getProperty("file.encoding", "");
            String sysEncoding = System.getProperty("sun.jnu.encoding");
            if (sysEncoding != null && !sysEncoding.equals(fileEncoding)) {
                systemLocale = Locale.ROOT;
            } else {
                String language = System.getProperty("user.language", "en");
                String country  = System.getProperty("user.country","");
                String variant  = System.getProperty("user.variant","");
                systemLocale = Locale.of(language, country, variant);
            }
        }
        return systemLocale;
    }

    void addToPool(FileFont font) {

        FileFont fontFileToClose = null;
        int freeSlot = -1;

        synchronized (fontFileCache) {
            /* Avoid duplicate entries in the pool, and don't close() it,
             * since this method is called only from within open().
             * Seeing a duplicate is most likely to happen if the thread
             * was interrupted during a read, forcing perhaps repeated
             * close and open calls and it eventually it ends up pointing
             * at the same slot.
             */
            for (int i=0;i<CHANNELPOOLSIZE;i++) {
                if (fontFileCache[i] == font) {
                    return;
                }
                if (fontFileCache[i] == null && freeSlot < 0) {
                    freeSlot = i;
                }
            }
            if (freeSlot >= 0) {
                fontFileCache[freeSlot] = font;
                return;
            } else {
                /* replace with new font. */
                fontFileToClose = fontFileCache[lastPoolIndex];
                fontFileCache[lastPoolIndex] = font;
                /* lastPoolIndex is updated so that the least recently opened
                 * file will be closed next.
                 */
                lastPoolIndex = (lastPoolIndex+1) % CHANNELPOOLSIZE;
            }
        }
        /* Need to close the font file outside of the synchronized block,
         * since its possible some other thread is in an open() call on
         * this font file, and could be holding its lock and the pool lock.
         * Releasing the pool lock allows that thread to continue, so it can
         * then release the lock on this font, allowing the close() call
         * below to proceed.
         * Also, calling close() is safe because any other thread using
         * the font we are closing() synchronizes all reading, so we
         * will not close the file while its in use.
         */
        if (fontFileToClose != null) {
            fontFileToClose.close();
        }
    }

    protected FontUIResource getFontConfigFUIR(String family, int style,
                                               int size)
    {
        return new FontUIResource(family, style, size);
    }
}
