Hi Phillip, I have written a desktop application which, on start up, refreshes a cache of fonts (using FOP code) and subsequently allows the user to refresh that cache by hitting a button (again, calls the same FOP code). See attached. When the application starts up I call FOPManager.refreshFonts( false );
Before allowing the user to initiate a print, I call FOPManager.isReady() When the user forces a cache update, I call FOPManager.refreshFonts( true ); My fopConfiguration.xml is standard and doesn't do anything fancy. Cheers, Bernard. > From: phillip.old...@gmail.com > Date: Tue, 12 Jun 2012 16:58:49 +0100 > Subject: Still having trouble loading fonts at runtime - suggestions? > To: fop-users@xmlgraphics.apache.org > > Hi All > > I'm still having trouble loading & using fonts while my app is > running. I can load fonts without issue when configuring them via the > XML config, but unfortunately the fonts are provided by a 3rd party at > runtime and I therefore need to find a way to load them via java. > > Here's my current process (not working): > > 1. create a new FOP instance > 2. load a number of default settings from an XML file > 3. override some of these settings (eg. resolution) based on certain > preferences passed in at runtime > > then, specifically regarding fonts: > > 4. create a temporary directory to store the font(s) that the 3rd > party is providing > 5. write each font to the temp directory > 6. pass the temp dir to FontManager.getFontBaseURL() > 7. process the FO file > > However, even though the FontBaseURL is changed, the fonts aren't > loaded/used during processing. Is there a way to tell FOP/the > FontManager to refresh it's cache/search the new directory and load > the fonts? Is there a better approach to this? > > -- > Phillip B Oldham > phillip.old...@gmail.com > > --------------------------------------------------------------------- > To unsubscribe, e-mail: fop-users-unsubscr...@xmlgraphics.apache.org > For additional commands, e-mail: fop-users-h...@xmlgraphics.apache.org >
import java.io.File; import java.io.IOException; import java.net.URL; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.SortedMap; import java.util.Vector; import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FopFactory; import org.apache.fop.fonts.FontEventListener; import org.apache.fop.fonts.FontTriplet; import org.apache.fop.fonts.autodetect.FontFileFinder; import org.apache.fop.tools.fontlist.FontListGenerator; import org.apache.log4j.Logger; public class FOPManager { private static final String PROPERTY_FONT_LIST = "FontList"; //$NON-NLS-1$ private static final String PROPERTY_FONT_FILES = "FontFiles"; //$NON-NLS-1$ protected static final FopFactory ms_fopFactory = FopFactory.newInstance(); protected static final Logger ms_logger = Logger.getLogger( FOPManager.class.getName() ); public static final boolean IS_MAC_OS_X = System.getProperty( "os.name" ).startsWith( "Mac OS X" ); //$NON-NLS-1$ //$NON-NLS-2$ protected static Vector<String> ms_fonts = null; protected static boolean ms_ready = false; protected static final HashMap<String, String> ms_fontsForMacOSX = new HashMap<String, String>(); protected static final HashMap<String, String> ms_fontsForWindows = new HashMap<String, String>(); static { try { ms_fopFactory.setUserConfig( new File( "fopConfiguration.xml" ) ); } //$NON-NLS-1$ catch( Exception exception ) { throw new RuntimeException( exception ); } ms_fontsForMacOSX.put( "en", "Arial" ); //$NON-NLS-1$ //$NON-NLS-2$ ms_fontsForWindows.put( "en", "Arial" ); //$NON-NLS-1$ //$NON-NLS-2$ // http://www.pinyinjoe.com/pinyin/pinyin_xpfonts.htm // http://www.yale.edu/chinesemac/pages/fonts.html ms_fontsForMacOSX.put( "zh", "Hei" ); //$NON-NLS-1$ //$NON-NLS-2$ ms_fontsForWindows.put( "zh", "SimHei" ); //$NON-NLS-1$ //$NON-NLS-2$ } public static FopFactory getFOPFactory() { return ms_fopFactory; } public static Vector<String> getFontList() { return ms_fonts; } public static boolean isReady() { return ms_ready; } public static void refreshFonts( boolean flush ) { ms_ready = false; if( flush ) { new InitialiseFonts().start(); return; } // Get the list of cached font names... ms_fonts = PropertiesManager.getInstance().getList( PROPERTY_FONT_LIST ); if( ms_fonts.isEmpty() ) { new InitialiseFonts().start(); return; } // We have a list of font names, assume it's good. // Now check the cached font files list against the actual font files list. Vector<String> fontFilesFromProperties = PropertiesManager.getInstance().getList( PROPERTY_FONT_FILES ); Vector<String> fontFiles = loadFontFiles(); if( fontFilesFromProperties.size() != fontFiles.size() ) { new InitialiseFonts().start(); return; } // Compare the font files lists, element by element... for( String fontFile : fontFiles ) for( int i = 0; i < fontFilesFromProperties.size(); i++ ) if( fontFile.compareTo( fontFilesFromProperties.get( i ) ) == 0 ) { fontFilesFromProperties.remove( i ); break; } if( ! fontFilesFromProperties.isEmpty() ) { new InitialiseFonts().start(); return; } // Font names are good and the font file lists match, so all good... ms_ready = true; } public static String getDefaultFont() { if( IS_MAC_OS_X ) return ms_fontsForMacOSX.get( Locale.getDefault().getLanguage() ); return ms_fontsForWindows.get( Locale.getDefault().getLanguage() ); } protected static Vector<String> loadFontFiles() { try { @SuppressWarnings("unchecked") List<URL> fontFiles = new FontFileFinder().find(); Vector<String> fontFilesAsStrings = new Vector<String>( fontFiles.size() ); for( URL url : fontFiles ) fontFilesAsStrings.add( url.toString() ); return fontFilesAsStrings; } catch( IOException ioException ) { throw new RuntimeException( ioException ); } } private static class InitialiseFonts extends Thread { public InitialiseFonts() { super(); } @Override public void run() { FontEventListener fontEventListener = new FontEventListener() { @Override public void fontLoadingErrorAtAutoDetection( Object source, String fontURL, Exception exception ) { ms_logger.error( "Could not load font '" + fontURL + "'.", exception ); } //$NON-NLS-1$ //$NON-NLS-2$ @Override public void fontSubstituted( Object source, FontTriplet requested, FontTriplet effective ) { /** Ignore. */ } @Override public void glyphNotAvailable( Object source, char ch, String fontName ) { /** Ignore. */ } }; try { SortedMap<?,?> fontFamilies = new FontListGenerator().listFonts( ms_fopFactory, org.apache.xmlgraphics.util.MimeConstants.MIME_PDF, fontEventListener ); ms_fonts = new Vector<String>( fontFamilies.size() ); Iterator<?> iterator = fontFamilies.entrySet().iterator(); while( iterator.hasNext() ) ms_fonts.add( ( (Map.Entry<?,?>)iterator.next() ).getKey().toString() ); PropertiesManager.getInstance().setList( PROPERTY_FONT_LIST, ms_fonts ); PropertiesManager.getInstance().setList( PROPERTY_FONT_FILES, loadFontFiles() ); PropertiesManager.getInstance().store(); ms_ready = true; } catch( FOPException fopException ) { throw new RuntimeException( fopException ); } } } }
--------------------------------------------------------------------- To unsubscribe, e-mail: fop-users-unsubscr...@xmlgraphics.apache.org For additional commands, e-mail: fop-users-h...@xmlgraphics.apache.org