3912 lines · 165.2 KB · Java
RawDownload
                fileName = jreOtherFontFiles[i];                if (fileName == null) {                    continue;                }                jreOtherFontFiles[i] = null;                physicalFont = initialiseDeferredFont(fileName);                if (physicalFont != null &&                    (physicalFont.getFontName(null).equalsIgnoreCase(name) ||                     physicalFont.getFamilyName(null).equalsIgnoreCase(name))                    && physicalFont.style == style) {                    return physicalFont;                }            }        }         return null;    }     /* This skips JRE installed fonts. */    private PhysicalFont findOtherDeferredFont(String name, int style) {        for (String fileName : deferredFontFiles.keySet()) {            File file = new File(fileName);            String dir = file.getParent();            String fname = file.getName();            if (dir != null &&                dir.equals(jreFontDirName) &&                jreLucidaFontFiles.contains(fname)) {                continue;            }            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.getLogger()                            .info("Opening deferred font file " + fileNameKey);        }         PhysicalFont physicalFont;        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,                                     getDefaultPhysicalFont().handle);            }        } else {            Font2DHandle handle = initialisedFonts.get(fileNameKey);            if (handle == null) {                /* Probably shouldn't happen, but just in case */                physicalFont = getDefaultPhysicalFont();            } 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 {            String name;             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);            default:             }            if (FontUtilities.isLogging()) {                FontUtilities.getLogger()                      .info("Registered file " + fileName + " as font " +                            physicalFont + " rank="  + fontRank);            }        } catch (FontFormatException ffe) {            if (FontUtilities.isLogging()) {                FontUtilities.getLogger().warning("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) {            /* findFont2D will load all fonts before giving up the search.             * If the JRE Lucida isn't found (eg because the JRE fonts             * directory is missing), it could find another version of Lucida             * from the host system. This is OK because at that point we are             * trying to gracefully handle/recover from a system             * misconfiguration and this is probably a reasonable substitution.             */            defaultPhysicalFont = (PhysicalFont)                findFont2D("Lucida Sans Regular", Font.PLAIN, NO_FALLBACK);            if (defaultPhysicalFont == null) {                defaultPhysicalFont = (PhysicalFont)                    findFont2D("Arial", Font.PLAIN, NO_FALLBACK);            }            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.                 */                Iterator i = physicalFonts.values().iterator();                if (i.hasNext()) {                    defaultPhysicalFont = (PhysicalFont)i.next();                } else {                    throw new Error("Probable fatal error:No fonts found.");                }            }        }        return defaultPhysicalFont;    }     public CompositeFont getDefaultLogicalFont(int style) {        return (CompositeFont)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();        }        return (String[])AccessController.doPrivileged(new PrivilegedAction() {            public Object run() {                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<String>();                    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<String>();                    }                    unmappedFontNames.add(font);                }            }        }         if (unmappedFontNames != null) {            HashSet<String> unmappedFontFiles = new HashSet<String>();             /* 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.             */            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<String>();                 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 family = familyToFontListMap.get(familyName);                        if (family != null) {                            if (family.size() <= 1) {                                familyToFontListMap.remove(familyName);                            }                        }                    }                    fontToFamilyNameMap.remove(name);                    if (FontUtilities.isLogging()) {                        FontUtilities.getLogger()                                             .info("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;        }

Lines 1001–1500 of 3912. Previous lines