3912 lines · 165.2 KB · Java
RawDownload
                            } 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);                        }                         /* On Solaris, we need to register the Japanese TrueType                         * directory so that we can find the corresponding                         * bitmap fonts. This could be done by listing the                         * directory in the font configuration file, but we                         * don't want to confuse users with this quirk. There                         * are no bitmap fonts for other writing systems that                         * correspond to TrueType fonts and have matching XLFDs.                         * We need to register the bitmap fonts only in                         * environments where they're on the X font path, i.e.,                         * in the Japanese locale. Note that if the X Toolkit                         * is in use the font path isn't set up by JDK, but                         * users of a JA locale should have it                         * set up already by their login environment.                         */                        if (FontUtilities.isSolaris && Locale.JAPAN.equals(Locale.getDefault())) {                            registerFontDir("/usr/openwin/lib/locale/ja/X11/fonts/TT");                        }                         initCompositeFonts(fontConfig, null);                         return null;                    }                });         boolean platformFont = AccessController.doPrivileged(                        new PrivilegedAction<Boolean>() {                                public Boolean run() {                                        String prop =                                                System.getProperty("java2d.font.usePlatformFont");                                        String env = System.getenv("JAVA2D_USEPLATFORMFONT");                                        return "true".equals(prop) || env != null;                                }                        });         if (platformFont) {            usePlatformFontMetrics = true;            System.out.println("Enabling platform font metrics for win32. This is an unsupported option.");            System.out.println("This yields incorrect composite font metrics as reported by 1.1.x releases.");            System.out.println("It is appropriate only for use by applications which do not use any Java 2");            System.out.println("functionality. This property will be removed in a later release.");        }    }     /**     * This method is provided for internal and exclusive use by Swing.     *     * @param font representing a physical font.     * @return true if the underlying font is a TrueType or OpenType font     * that claims to support the Microsoft Windows encoding corresponding to     * the default file.encoding property of this JRE instance.     * This narrow value is useful for Swing to decide if the font is useful     * for the the Windows Look and Feel, or, if a  composite font should be     * used instead.     * The information used to make the decision is obtained from     * the ulCodePageRange fields in the font.     * A caller can use isLogicalFont(Font) in this class before calling     * this method and would not need to call this method if that     * returns true.     *///     static boolean fontSupportsDefaultEncoding(Font font) {//      String encoding =//          (String) java.security.AccessController.doPrivileged(//                new sun.security.action.GetPropertyAction("file.encoding")); //      if (encoding == null || font == null) {//          return false;//      } //      encoding = encoding.toLowerCase(Locale.ENGLISH); //      return FontManager.fontSupportsEncoding(font, encoding);//     }     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 = (Font2D)            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.getLogger().info("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     */    private PhysicalFont addToFontList(PhysicalFont f, int rank) {         String fontName = f.fullName;        String familyName = f.familyName;        if (fontName == null || "".equals(fontName)) {            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.getLogger().info("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 if (family.getRank() >= rank) {                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.getLogger()                              .warning("Unexpected attempt to replace a JRE " +                                       " font " + fontName + " from " +                                        oldFont.platName +                                       " with " + newFont.platName);                    }                    return oldFont;                }                 if (FontUtilities.isLogging()) {                    FontUtilities.getLogger()                          .info("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 if (family.getRank() >= rank) {                    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<String, FontRegistrationInfo>();    private final ConcurrentHashMap<String, Font2DHandle>        initialisedFonts = new ConcurrentHashMap<String, Font2DHandle>();     /* 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);    }     /* We keep a map of the files which contain the Lucida fonts so we     * don't need to search for them.     * But since we know what fonts these files contain, we can also avoid     * opening them to look for a font name we don't recognise - see     * findDeferredFont().     * For typical cases where the font isn't a JRE one the overhead is     * this method call, HashMap.get() and null reference test, then     * a boolean test of noOtherJREFontFiles.     */    public    /*private*/ PhysicalFont findJREDeferredFont(String name, int style) {         PhysicalFont physicalFont;        String nameAndStyle = name.toLowerCase(Locale.ENGLISH) + style;        String fileName = jreFontMap.get(nameAndStyle);        if (fileName != null) {            fileName = jreFontDirName + File.separator + fileName;            if (deferredFontFiles.get(fileName) != null) {                physicalFont = initialiseDeferredFont(fileName);                if (physicalFont != null &&                    (physicalFont.getFontName(null).equalsIgnoreCase(name) ||                     physicalFont.getFamilyName(null).equalsIgnoreCase(name))                    && physicalFont.style == style) {                    return physicalFont;                }            }        }         /* 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 only the Lucidas will be present and jreOtherFontFiles         * will be empty.         * noOtherJREFontFiles is used so we can skip this block as soon         * as its determined that its not needed - almost always after the         * very first time through.         */        if (noOtherJREFontFiles) {            return null;        }        synchronized (jreLucidaFontFiles) {            if (jreOtherFontFiles == null) {                HashSet<String> otherFontFiles = new HashSet<String>();                for (String deferredFile : deferredFontFiles.keySet()) {                    File file = new File(deferredFile);                    String dir = file.getParent();                    String fname = file.getName();                    /* skip names which aren't absolute, aren't in the JRE                     * directory, or are known Lucida fonts.                     */                    if (dir == null ||                        !dir.equals(jreFontDirName) ||                        jreLucidaFontFiles.contains(fname)) {                        continue;                    }                    otherFontFiles.add(deferredFile);                }                jreOtherFontFiles = otherFontFiles.toArray(STR_ARRAY);                if (jreOtherFontFiles.length == 0) {                    noOtherJREFontFiles = true;                }            }             for (int i=0; i<jreOtherFontFiles.length;i++) {

Lines 501–1000 of 3912. Previous lines