3912 lines · 165.2 KB · Java
RawDownload
         * 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.getLogger()                          .info("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<String, Font2D>();     /*     * 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) {        String lowerCaseName = name.toLowerCase(Locale.ENGLISH);        String mapName = lowerCaseName + dotStyleStr(style);        Font2D font;         /* 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.         */        if (_usingPerAppContextComposites) {            ConcurrentHashMap<String, Font2D> altNameCache =                (ConcurrentHashMap<String, Font2D>)                AppContext.getAppContext().get(CompositeFont.class);            if (altNameCache != null) {                font = (Font2D)altNameCache.get(mapName);            } else {                font = null;            }        } else {            font = fontNameCache.get(mapName);        }        if (font != null) {            return font;        }         if (FontUtilities.isLogging()) {            FontUtilities.getLogger().info("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 = 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.getLogger()                    .info("findFontFromPlatformMap returned " + font);            }            if (font != null) {                fontNameCache.put(mapName, font);                return font;            }             /* Don't want Windows to return a Lucida Sans font from             * C:\Windows\Fonts             */            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.getLogger()                          .info("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;            }        }         /* Some apps use deprecated 1.0 names such as helvetica and courier. On         * Solaris these are Type1 fonts in /usr/openwin/lib/X11/fonts/Type1.         * If running on Solaris will register all the fonts in this         * directory.         * May as well register the whole directory without actually testing         * the font name is one of the deprecated names as the next step would         * load all fonts which are in this directory anyway.         * In the event that this lookup is successful it potentially "hides"         * TrueType versions of such fonts that are elsewhere but since they         * do not exist on Solaris this is not a problem.         * Set a flag to indicate we've done this registration to avoid         * repetition and more seriously, to avoid recursion.         */        if (FontUtilities.isSolaris &&!loaded1dot0Fonts) {            /* "timesroman" is a special case since that's not the             * name of any known font on Solaris or elsewhere.             */            if (lowerCaseName.equals("timesroman")) {                font = findFont2D("serif", style, fallback);                fontNameCache.put(mapName, font);            }            register1dot0Fonts();            loaded1dot0Fonts = true;            Font2D ff = findFont2D(name, style, fallback);            return ff;        }         /* 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 || fontsAreRegisteredPerAppContext) {            Hashtable<String, FontFamily> familyTable = null;            Hashtable<String, Font2D> nameTable;             if (fontsAreRegistered) {                familyTable = createdByFamilyName;                nameTable = createdByFullName;            } else {                AppContext appContext = AppContext.getAppContext();                familyTable =                    (Hashtable<String,FontFamily>)appContext.get(regFamilyKey);                nameTable =                    (Hashtable<String,Font2D>)appContext.get(regFullNameKey);            }             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.getLogger()                                       .info("Load fonts looking for:" + name);            }            loadFonts();            loadedAllFonts = true;            return findFont2D(name, style, fallback);        }         if (!loadedAllFontFiles) {            if (FontUtilities.isLogging()) {                FontUtilities.getLogger()                                  .info("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.getLogger().info("No font found for:" + name);        }         switch (fallback) {        case PHYSICAL_FALLBACK: return getDefaultPhysicalFont();        case LOGICAL_FALLBACK: return getDefaultLogicalFont(style);        default: return null;        }    }     /*     * Workaround for apps which are dependent on a font metrics bug     * in JDK 1.1. This is an unsupported win32 private setting.     * Left in for a customer - do not remove.     */    public boolean usePlatformFontMetrics() {        return usePlatformFontMetrics;    }     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);     private Thread fileCloser = null;    Vector<File> tmpFontFiles = null;     public Font2D createFont2D(File fontFile, int fontFormat,                               boolean isCopy, CreatedFontTracker tracker)    throws FontFormatException {         String fontFilePath = fontFile.getPath();        FileFont font2D = null;        final File fFile = fontFile;        final CreatedFontTracker _tracker = tracker;        try {            switch (fontFormat) {            case Font.TRUETYPE_FONT:                font2D = new TrueTypeFont(fontFilePath, null, 0, true);                break;            case Font.TYPE1_FONT:                font2D = new Type1Font(fontFilePath, null, isCopy);                break;            default:                throw new FontFormatException("Unrecognised Font Format");            }        } catch (FontFormatException e) {            if (isCopy) {                java.security.AccessController.doPrivileged(                     new java.security.PrivilegedAction() {                          public Object run() {                              if (_tracker != null) {                                  _tracker.subBytes((int)fFile.length());                              }                              fFile.delete();                              return null;                          }                });            }            throw(e);        }        if (isCopy) {            font2D.setFileToRemove(fontFile, tracker);            synchronized (FontManager.class) {                 if (tmpFontFiles == null) {                    tmpFontFiles = new Vector<File>();                }                tmpFontFiles.add(fontFile);                 if (fileCloser == null) {                    final Runnable fileCloserRunnable = new Runnable() {                      public void run() {                         java.security.AccessController.doPrivileged(                         new java.security.PrivilegedAction() {                         public Object 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()];

Lines 2001–2500 of 3912. Previous lines