3912 lines · 165.2 KB · Java
RawDownload
         * 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 (regFamilyKey) {            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;        Hashtable<String,Font2D> fullNameTable;        if (!maybeMultiAppContext()) {            familyTable = createdByFamilyName;            fullNameTable = createdByFullName;            fontsAreRegistered = true;        } else {            AppContext appContext = AppContext.getAppContext();            familyTable =                (Hashtable<String,FontFamily>)appContext.get(regFamilyKey);            fullNameTable =                (Hashtable<String,Font2D>)appContext.get(regFullNameKey);            if (familyTable == null) {                familyTable = new Hashtable<String,FontFamily>();                fullNameTable = new Hashtable<String,Font2D>();                appContext.put(regFamilyKey, familyTable);                appContext.put(regFullNameKey, fullNameTable);            }            fontsAreRegisteredPerAppContext = 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 = (String[])(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 if (fontsAreRegisteredPerAppContext) {            AppContext appContext = AppContext.getAppContext();            familyTable =                (Hashtable<String,FontFamily>)appContext.get(regFamilyKey);        } 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 if (fontsAreRegisteredPerAppContext) {            AppContext appContext = AppContext.getAppContext();            nameTable =                (Hashtable<String,Font2D>)appContext.get(regFullNameKey);        } 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<String>();        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.     */    public abstract String[] getDefaultPlatformFont();     // Begin: Refactored from SunGraphicsEnviroment.     /*     * 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.getLogger()                                         .warning("skip bad font " + fullName);                }                continue; // skip this font file.            }             registeredFontFiles.add(fullName);             if (FontUtilities.debugFonts()                && FontUtilities.getLogger().isLoggable(PlatformLogger.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.getLogger().info(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;    }     public static boolean isOpenJDK() {        return FontUtilities.isOpenJDK;    }     protected void loadFonts() {        if (discoveredAllFonts) {            return;        }        /* Use lock specific to the font system */        synchronized (this) {            if (FontUtilities.debugFonts()) {                Thread.dumpStack();                FontUtilities.getLogger()                            .info("SunGraphicsEnvironment.loadFonts() called");            }            initialiseDeferredFonts();             java.security.AccessController.doPrivileged(                                    new java.security.PrivilegedAction() {                public Object run() {                    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;                    return null;                }            });        }    }     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);    }     private void registerFontsInDir(String dirName, boolean useJavaRasterizer,                                    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() {        if (defaultFontFileName == null) {            initDefaultFonts();        }        return defaultFontFileName;    }     private void initDefaultFonts() {        if (!isOpenJDK()) {            defaultFontName = lucidaFontName;            if (useAbsoluteFontFileNames()) {                defaultFontFileName =                    jreFontDirName + File.separator + FontUtilities.LUCIDA_FILE_NAME;            } else {                defaultFontFileName = FontUtilities.LUCIDA_FILE_NAME;            }        }    }     /**     * 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() {        if (defaultFontName == null) {            initDefaultFonts();        }        return defaultFontName;    }     public void loadFontFiles() {        loadFonts();        if (loadedAllFontFiles) {            return;        }        /* Use lock specific to the font system */        synchronized (this) {            if (FontUtilities.debugFonts()) {                Thread.dumpStack();                FontUtilities.getLogger().info("loadAllFontFiles() called");            }            java.security.AccessController.doPrivileged(                                    new java.security.PrivilegedAction() {                public Object run() {                    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;                    return null;                }            });        }    }     /*     * 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.getLogger()                            .info("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.                     */

Lines 3001–3500 of 3912. Previous lines