RE: Still having trouble loading fonts at runtime - suggestions?
Hi Bernard Thanks for that code - that's really helpful. However, from what I can tell (java isn't one of my main languages, I'm a Python dev) it seems as though it doesn't actually tell FOP to reload any fonts, but rather gathers a list of fonts and then asks `PropertiesManager` to set the fonts. I can't see a reference to `PropertiesManager` in the FOP docs; is that a class in your app, or am I missing something? Cheers, Phill Bernmeister wrote: 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. -- View this message in context: http://old.nabble.com/Still-having-trouble-loading-fonts-at-runtime---suggestions--tp34000790p34005767.html Sent from the FOP - Users mailing list archive at Nabble.com. - To unsubscribe, e-mail: fop-users-unsubscr...@xmlgraphics.apache.org For additional commands, e-mail: fop-users-h...@xmlgraphics.apache.org
RE: Still having trouble loading fonts at runtime - suggestions?
Hi Phill, The PropertiesManager is a class of mine which basically extends java.util.Properties and essentially reads/writes a hash table of key/value pairs. I store in the properties a list of the font names and their respective font files (as discovered via FOP). For me on Ubuntu 12.04 I get: FontList=Andale Mono,Arial,Arial Black,Bitstream Charter,Century Schoolbook L,Comic Sans MS,Courier,...FontFiles=file\:/usr/share/fonts/truetype/openoffice/opens___.ttf,file\:/usr/share/fonts/truetype/ttf-khmeros-core/KhmerOS.ttf,... I cannot remember precisely why I had to implement this cache but I think it had to do with supporting i18n. Originally I simply used the hard coded default fonts which FOP provided but I found on some non-English machines I'd get the 'square' symbol and so wanted to provide a way for a user to specify a font to use for the render. To do this I got FOP to tell me what fonts were available and present that to the user. I just cache that information so I don't have to ask FOP each time (which can take a few minutes). When I do the render I pass the font name as one of the transformer parameters: xslParams.put( font-family, (String)m_fontName.getSelectedItem() ); where m_fontName is the selected font name in the JComboBox shown to the user. Cheers, Bernard. Date: Wed, 13 Jun 2012 06:41:58 -0700 From: phillip.old...@gmail.com To: fop-users@xmlgraphics.apache.org Subject: RE: Still having trouble loading fonts at runtime - suggestions? Hi Bernard Thanks for that code - that's really helpful. However, from what I can tell (java isn't one of my main languages, I'm a Python dev) it seems as though it doesn't actually tell FOP to reload any fonts, but rather gathers a list of fonts and then asks `PropertiesManager` to set the fonts. I can't see a reference to `PropertiesManager` in the FOP docs; is that a class in your app, or am I missing something? Cheers, Phill
RE: Still having trouble loading fonts at runtime - suggestions?
Hi Phill, I make a call to FOP itself to find the fonts - see FOPManager::InitialiseFonts in the code from my first reply. The magic line is SortedMap?,? fontFamilies = new FontListGenerator().listFonts( ms_fopFactory, org.apache.xmlgraphics.util.MimeConstants.MIME_PDF, fontEventListener ); I've looked at the FOP internal code and they simply squirrel through various directories, based on the current OS, to find font files. I call this code and then simply cache that information. I suspect to add a font in at runtime you'd need to configure that in the FOP configuration file - never had to do this myself. Cheers, Bernard. Date: Wed, 13 Jun 2012 07:20:46 -0700 From: phillip.old...@gmail.com To: fop-users@xmlgraphics.apache.org Subject: RE: Still having trouble loading fonts at runtime - suggestions? Hi Bernard Thanks for that explanation; that makes a lot of sense now. I think I'm still having a little trouble working out which are the line(s) where you're telling FOP which fonts are available, though. Specifically what I have is a byte-array containing a font's data, and I need to make FOP use that font when it renders an FO (there's no XSL translation - that has already been done). I've been through the docs a number of times now, but I can't see where I can add a font manually to FOP's runtime config, or tell it to refresh it's font cache after providing a directory of fonts, or anything like that. :(
RE: Still having trouble loading fonts at runtime - suggestions?
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 VectorString ms_fonts = null; protected static boolean ms_ready = false; protected static final HashMapString, String ms_fontsForMacOSX = new HashMapString, String(); protected static final HashMapString, String ms_fontsForWindows = new HashMapString, 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 VectorString 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. VectorString fontFilesFromProperties = PropertiesManager.getInstance().getList( PROPERTY_FONT_FILES ); VectorString 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