/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2002 - 2008, Open Source Geospatial Foundation (OSGeo) * (C) 2008 - 2009, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library 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 * Lesser General Public License for more details. */ package org.geotoolkit.renderer.style; import org.geotoolkit.font.IconBuilder; import java.awt.Font; import java.awt.FontFormatException; import java.awt.GraphicsEnvironment; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; /** * Lookup and caches font definitions for faster retrieval * * @author Andrea Aime - TOPP * * @module */ public class FontCache { /** The logger for the rendering module. */ private static final Logger LOGGER = org.apache.sis.util.logging.Logging .getLogger("org.geotoolkit.renderer.style"); private static FontCache defaultInstance; /** Set containing the font families known of this machine */ private Set<String> fontFamilies = null; /** Fonts already loaded */ private Map<String, Font> loadedFonts = new HashMap<String, Font>(); /** * Returns the default, system wide font cache */ public static FontCache getDefaultInsance() { if (defaultInstance == null) { defaultInstance = new FontCache(); defaultInstance.loadedFonts.put(IconBuilder.FONT.getFamily(),IconBuilder.FONT); } return defaultInstance; } public synchronized Font getFont(final String requestedFont) { // make sure we load the known font families once if (fontFamilies == null) { final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); fontFamilies = new HashSet<String>(Arrays.asList(ge.getAvailableFontFamilyNames())); if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.finest("there are " + fontFamilies.size() + " fonts available"); } } // see if the font has already been loaded if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.finest("trying to load " + requestedFont); } if (loadedFonts.containsKey(requestedFont)) { return loadedFonts.get(requestedFont); } if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.finest("not already loaded"); } // if not, try to load from the java runtime or as an URL final Font javaFont; if (fontFamilies.contains(requestedFont)) { javaFont = new Font(requestedFont, Font.PLAIN, 12); } else { if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.finest("not a system font"); } javaFont = loadFromUrl(requestedFont); } // log the result and exit if(javaFont == null) { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("Could not load font " + requestedFont); } } else { loadedFonts.put(requestedFont, javaFont); } return javaFont; } /** * Tries to load the specified font name as a URL * @param fontUrl * @return */ Font loadFromUrl(final String fontUrl) { // may be its a file or url InputStream is = null; if (fontUrl.startsWith("http") || fontUrl.startsWith("file:") || fontUrl.startsWith("jar:")) { try { URL url = new URL(fontUrl); is = url.openStream(); } catch (MalformedURLException mue) { // this may be ok - but we should mention it if (LOGGER.isLoggable(Level.INFO)) { LOGGER.info("Bad url in SLDStyleFactory " + fontUrl + "\n" + mue); } } catch (IOException ioe) { // we'll ignore this for the moment if (LOGGER.isLoggable(Level.INFO)) { LOGGER.info("IO error in SLDStyleFactory " + fontUrl + "\n" + ioe); } } } else { if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.finest("not a URL"); } File file = new File(fontUrl); try { is = new FileInputStream(file); } catch (FileNotFoundException fne) { // this may be ok - but we should mention it if (LOGGER.isLoggable(Level.INFO)) { LOGGER.info("Bad file name in SLDStyleFactory" + fontUrl + "\n" + fne); } } } // make sure we have anything to load if (is == null) { if (LOGGER.isLoggable(Level.INFO)) { LOGGER.info("null input stream, could not load the font"); } return null; } if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.finest("about to load"); } try { return Font.createFont(Font.TRUETYPE_FONT, is); } catch (FontFormatException ffe) { if (LOGGER.isLoggable(Level.INFO)) { LOGGER.info("Font format error in SLDStyleFactory " + fontUrl + "\n" + ffe); } return null; } catch (IOException ioe) { // we'll ignore this for the moment if (LOGGER.isLoggable(Level.INFO)) { LOGGER.info("IO error in SLDStyleFactory " + fontUrl + "\n" + ioe); } return null; } } }