Re: SOLVED - sort of Re how to embed a font programatically
Karl, thanks for the heads-up. One comment on your Java class: To improve performance you should reuse the FopFactory and the TransformerFactory instead of constructing them each time. See also: http://xmlgraphics.apache.org/fop/trunk/embedding.html#basics On 19.04.2006 02:09:24 Karl Roberts wrote: Hi Jeremias, FYI I've now had time to try the latest FOP trunk and patch it into my code (instead of my workaround) and I can confirm the the URL resolving issues when deploying FOP in a webapp so that URL's can be relative to the ServletContext are gone when using the ServletContextURIResolver and the FopFactory helper methods to set it up. External graphics url's in the xsl-fo file are resolved OK (when the URL scheme is servlet-context: ) And all references to the font metrics-url and embed-url in the fopconfig xml are also resolved OK (again using the servlet-context: scheme) Thanks for all your help, it's a pleasure to use such an activly maintained piece of software like FOP. Cheers Karl PS for anyone wondering what this thread is about see the following code snippets and config xml to see how to use the ServletContextURIResolver to resolve URL's in XSL-FO and FOP config file relative to a web applications ServletContext. // code snippet ... public void PDFDocumentGenerator(InputSource fopconfigInputSource, ServletContext context, Source xmlSrc, Source xslSrc){ //Set up stuff from fop config file if it exists if(fopconfigInputSource!=null) { try{ DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder(); Configuration cfg = cfgBuilder.build(this.fopconfigInputSource); FopFactory ff =FopFactory.newInstance(); ff.setUserConfig(cfg); FOUserAgent userAgent=ff.newFOUserAgent(); //If ServletContext is not null then add ServletContextURIResolver // incase URI's in the config file and xsl-fo input are special ones that are relative to servlet-context: if(context!=null) { ff.setURIResolver(new ServletContextURIResolver(context)); } ByteArrayOutputStream out = new ByteArrayOutputStream(); // Construct fop with desired output format Fop fop = ff.newFop(MimeConstants.MIME_PDF, userAgent,out); // Setup XSLT if exists// if not then we are assuming src is already in xsl-fo format TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer; if(xslSource!=null) { transformer = factory.newTransformer(xslSrc); } else { transformer = factory.newTransformer(); } // Resulting SAX events (the generated FO) must be piped through // to FOP Result res = new SAXResult(fop.getDefaultHandler()); // Start XSLT transformation and FOP processing transformer.transform(xmlSrc, res); //got here so no transform exceptions now deal with the output collect as byte array (or just stream it somewhere) byte[] theBytes= out.toByteArray(); .etc }catch(Exception e) { deal with it ...} } } // fopconfig.xml using url's with servlet-context scheme fop version=1.0 !-- Base URL for resolving relative URLs -- base.//base source-resolution72/source-resolution target-resolution72/target-resolution !-- ie A4 -- default-page-settings height=29.7cm width=21cm/ renderers renderer mime=application/pdf filterList valueflate/value /filterList fonts font metrics-url=servlet-context:///WEB-INF/Arial.xml kerning=no embed-url=servlet-context:///WEB-INF/arial.ttf font-triplet name=Arial style=normal weight=normal/ font-triplet name=ArialMT style=normal weight=normal/ /font font metrics-url=servlet-context:///WEB-INF/ArialBd.xml kerning=no embed-url=servlet-context:///WEB-INF/arialbd.ttf font-triplet name=Arial style=normal weight=bold/ font-triplet name=ArialMT style=normal weight=bold/ /font /fonts /renderer /renderers /fop snip/ Jeremias Maerki - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
RE: SOLVED - sort of Re how to embed a font programatically
Hi Jeremias, FYI I've now had time to try the latest FOP trunk and patch it into my code (instead of my workaround) and I can confirm the the URL resolving issues when deploying FOP in a webapp so that URL's can be relative to the ServletContext are gone when using the ServletContextURIResolver and the FopFactory helper methods to set it up. External graphics url's in the xsl-fo file are resolved OK (when the URL scheme is servlet-context: ) And all references to the font metrics-url and embed-url in the fopconfig xml are also resolved OK (again using the servlet-context: scheme) Thanks for all your help, it's a pleasure to use such an activly maintained piece of software like FOP. Cheers Karl PS for anyone wondering what this thread is about see the following code snippets and config xml to see how to use the ServletContextURIResolver to resolve URL's in XSL-FO and FOP config file relative to a web applications ServletContext. // code snippet ... public void PDFDocumentGenerator(InputSource fopconfigInputSource, ServletContext context, Source xmlSrc, Source xslSrc){ //Set up stuff from fop config file if it exists if(fopconfigInputSource!=null) { try{ DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder(); Configuration cfg = cfgBuilder.build(this.fopconfigInputSource); FopFactory ff =FopFactory.newInstance(); ff.setUserConfig(cfg); FOUserAgent userAgent=ff.newFOUserAgent(); //If ServletContext is not null then add ServletContextURIResolver // incase URI's in the config file and xsl-fo input are special ones that are relative to servlet-context: if(context!=null) { ff.setURIResolver(new ServletContextURIResolver(context)); } ByteArrayOutputStream out = new ByteArrayOutputStream(); // Construct fop with desired output format Fop fop = ff.newFop(MimeConstants.MIME_PDF, userAgent,out); // Setup XSLT if exists// if not then we are assuming src is already in xsl-fo format TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer; if(xslSource!=null) { transformer = factory.newTransformer(xslSrc); } else { transformer = factory.newTransformer(); } // Resulting SAX events (the generated FO) must be piped through // to FOP Result res = new SAXResult(fop.getDefaultHandler()); // Start XSLT transformation and FOP processing transformer.transform(xmlSrc, res); //got here so no transform exceptions now deal with the output collect as byte array (or just stream it somewhere) byte[] theBytes= out.toByteArray(); .etc }catch(Exception e) { deal with it ...} } } // fopconfig.xml using url's with servlet-context scheme fop version=1.0 !-- Base URL for resolving relative URLs -- base.//base source-resolution72/source-resolution target-resolution72/target-resolution !-- ie A4 -- default-page-settings height=29.7cm width=21cm/ renderers renderer mime=application/pdf filterList valueflate/value /filterList fonts font metrics-url=servlet-context:///WEB-INF/Arial.xml kerning=no embed-url=servlet-context:///WEB-INF/arial.ttf font-triplet name=Arial style=normal weight=normal/ font-triplet name=ArialMT style=normal weight=normal/ /font font metrics-url=servlet-context:///WEB-INF/ArialBd.xml kerning=no embed-url=servlet-context:///WEB-INF/arialbd.ttf font-triplet name=Arial style=normal weight=bold/ font-triplet name=ArialMT style=normal weight=bold/ /font /fonts /renderer /renderers /fop -Original Message- From: Karl Roberts Sent: Tuesday, 28 March 2006 8:48 AM To: fop-users@xmlgraphics.apache.org Subject: RE: SOLVED - sort of Re how to embed a font programatically Cheers Jeremias, FYI BEFORE you fix it, the issue exists in another place too! When embedding a TTF font (before I was using enc-ansi so never saw the issue) inside the ServletContext the following method also calls URL.openstream() rather than using the URIResolver org.apache.fop.pdf.PDFDocument.resolveURI(String uri) The TODO gives it away! todo Temporary hack to compile, improve later ;-) Cheers Karl PS my code looked too complex to me too, I agree that a direct setter method is a nicer option and look forward to testing it! My code was just a hack to get around the issue while highlighting
RE: SOLVED - sort of Re how to embed a font programatically
Hi Jeremias, Don't worry next time I'll create a patch for bugzilla! :-) Where are the changes so I can test them? I am not using FOUserAgent more than once per rendering run. The ThreadLocal stuff was there to guarantee that the FOUserAgent being used was thread safe, when the FontReder.createFont(String path) method calls AgentHelper.getInstance().getFOUserAgent(). The reason is because I am using FOP embedded from within a clustered Web App environment and putting a ServletContextURIReader in FOUserAgent. ServletContextURIReader has a reference to the ServletContext in it's constructor, and so I just wanted to guarantee that the FOUserAgent I'm using had the same ServletContext reference if it was pre-empted, given that the AgentHelper uses a static Singleton. If the UserAgent had been referencable to FontReder.createFont(String path) I'd have used it. Cheers Karl -Original Message- From: Jeremias Maerki [mailto:[EMAIL PROTECTED] Sent: Sunday, 26 March 2006 1:45 AM To: fop-users@xmlgraphics.apache.org Subject: Re: SOLVED - sort of Re how to embed a font programatically Karl, sorry for the huge delay. When I don't have a patch marked as such in our Bugzilla, I sometimes miss things even though your posts have remained unread in my inbox. It would be great if you could create a diff file (svn diff) next time you'd like to propose a change and put that in Bugzilla. That makes things a lot easier for us. Anyway, I've looked at what you've done. I must say that I didn't really get what that ThreadLocal was supposed to accomplish. I did various tests with servlet-context: URIs and made sure that relative URIs are now properly resolved. Everything should be fine now. Please test these changes on your end so we're sure I've covered everything and the NPEs have gone away. Does your use of ThreadLocal mean you're reusing the FOUserAgent for each rendering run? I'll soon merge some changes into FOP Trunk which should make the whole thing a lot cleaner. The FOUserAgent instance is not supposed to be reused for each rendering run. On 26.02.2006 23:11:33 Karl Roberts wrote: Hi Jeremias, Thanks for the update to Trunk, Your code was a bit tidier than mine, but did the same thing, However I still got the NullPointerException. The crux of the problem was that The URIReader was only being used to resolve URI's for Images in the XSLT to transform my XML to XSL-FO. It was not being used to resolve the URI of the font information passed in via the fopconfig.xml file. I traced the null pointer to a line in the createFont(String path) method of FontReader:- parser.parse(path); The javadoc for XMLReader.parse(String systemID) states that: If the system identifier is a URL, it must be fully resolved by the application before it is passed to the parser. However because it had not gon through the ServletContextURIResolver the String passed in was still like servet-context:///WEB-INF/fontinfo.xml. What would have been nice was the ability to inject a FontReader in the same way as URIReader can be injected into the FOUserAgent before it is passed to the Fop constructor, but I realised that the path should always be fully resolved and if a custom URIReader is injected, then we should use the FOUserAgent.resolveURI(String path) method to do it. I solved the problem (comments welcome) by createing a ThreadLocal Singleton (to attempt to avoid threading issues when used within a servlet) called AgentHelper that is initialised in the Fop Constructor:- /** modified Fop constructor **/ public Fop(String outputFormat, FOUserAgent ua) { this.outputFormat = outputFormat; foUserAgent = ua; if (foUserAgent == null) { foUserAgent = new FOUserAgent(); } boolean setOK = AgentHelper.getInstance().setFOUserAgent(foUserAgent); } And edited the FontReder.createFont(String path) method as follows, so that it uses the URIReader on the path first: /** Modified FontReader.createFont method **/ private void createFont(String path) throws FOPException { XMLReader parser = null; try { final SAXParserFactory factory = javax.xml.parsers.SAXParserFactory.newInstance(); factory.setNamespaceAware(true); parser = factory.newSAXParser().getXMLReader(); } catch (Exception e) { throw new FOPException(e); } if (parser == null) { throw new FOPException(Unable to create SAX parser); } try { parser.setFeature(http://xml.org/sax/features/namespace-prefixes;, false); } catch (SAXException e) { throw new FOPException(You need a SAX parser which supports SAX version 2, e); } parser.setContentHandler(this); try
Re: SOLVED - sort of Re how to embed a font programatically
Hi Karl On 27.03.2006 05:39:01 Karl Roberts wrote: Hi Jeremias, Don't worry next time I'll create a patch for bugzilla! :-) Where are the changes so I can test them? In our Subversion repository in Trunk, of course. See: http://xmlgraphics.apache.org/fop/download.html#source You should download the latest sources using Subversion. I am not using FOUserAgent more than once per rendering run. The ThreadLocal stuff was there to guarantee that the FOUserAgent being used was thread safe, when the FontReder.createFont(String path) method calls AgentHelper.getInstance().getFOUserAgent(). Ah, I see. FontReader (or any other class from the font package for that matter) should not reference FOUserAgent. That's why I added the FontResolver. The DefaultFontResolver in the render package contains the reference to FOUserAgent to keep the dependencies clean. The reason is because I am using FOP embedded from within a clustered Web App environment and putting a ServletContextURIReader in FOUserAgent. ServletContextURIReader has a reference to the ServletContext in it's constructor, and so I just wanted to guarantee that the FOUserAgent I'm using had the same ServletContext reference if it was pre-empted, given that the AgentHelper uses a static Singleton. Looks too complicated to me. It's probably better to add a setter method to ServletContextURIResolver (not Reader!) to update the ServletContext if that changes. This can be done in the doGet() method. When I've finished my current task of merging our API finalization branch back into Trunk, I'll do that, too. If the UserAgent had been referencable to FontReder.createFont(String path) I'd have used it. snip/ Jeremias Maerki - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: SOLVED - sort of Re how to embed a font programatically
to defeat instantiation. } private static class ThreadLocalFOUserAgent extends ThreadLocal {} private ThreadLocalFOUserAgent tlAgent = new ThreadLocalFOUserAgent(); public static AgentHelper getInstance() { return singleton; //no syncronization needed as statically initialised } public FOUserAgent getFOUserAgent() { synchronized (tlAgent) { return (FOUserAgent) tlAgent.get(); } } /** * Only allows foUserAgent to be set once, I would have used a final, * except it is placed in the ThreadLocal object. * * @param foUserAgent */ public boolean setFOUserAgent(FOUserAgent foUserAgent) { boolean ret = false; synchronized (tlAgent) { if (tlAgent.get() == null) { tlAgent.set(foUserAgent); ret = true; } } return ret; } } Any thoughts on how this could be improoved and added to the Trunk so that I don't have to maintain a separate branch of FOP? Cheers Karl Roberts -Original Message- From: Jeremias Maerki [mailto:[EMAIL PROTECTED] Sent: Thursday, 23 February 2006 9:56 PM To: fop-users@xmlgraphics.apache.org Subject: Re: Re how to embed a font programatically Have you seen my other post? I've implemented exactly what I proposed to you and put it in FOP Trunk: http://svn.apache.org/viewcvs?rev=379810view=rev More comments inline... On 23.02.2006 07:02:33 Karl Roberts wrote: Hi I built a URIResolver that reads URL's like: servlet-context:/WEB-INF/metric.xml And it works fine, however when it encounters a URL that doesn't match the servlet-context scheme I return null. That's correct IMO. It's what I did. However I then get an NullPointerException Caused by: javax.xml.transform.TransformerException: java.lang.NullPointerException at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform (T ransformerImpl.java:647) at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform (T ransformerImpl.java:279) Hmm, I don't get these with my implementation. TransformerException is not the real exception. Look further down in the stack trace where you should find the right place where the exception occurred. The above doesn't really help. Setting an exception breakpoint for NullPointerException will also be useful. I do return null from my URIResolver in the cases where the scheme doesn't match the one I'm after, and FOURIResolver kicks in, but it never seems to come back to my URIResolver. Should I instead delegate to FOURIResolver rather than return null? No, I don't think so. There must be something else that's wrong. Can you try my implementation instead? http://svn.apache.org/repos/asf/xmlgraphics/fop/trunk/src/java/org/apach e/fop/servlet/ServletContextURIResolver.java snip/ Jeremias Maerki - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
RE: SOLVED - sort of Re how to embed a font programatically
; } } Any thoughts on how this could be improoved and added to the Trunk so that I don't have to maintain a separate branch of FOP? Cheers Karl Roberts -Original Message- From: Jeremias Maerki [mailto:[EMAIL PROTECTED] Sent: Thursday, 23 February 2006 9:56 PM To: fop-users@xmlgraphics.apache.org Subject: Re: Re how to embed a font programatically Have you seen my other post? I've implemented exactly what I proposed to you and put it in FOP Trunk: http://svn.apache.org/viewcvs?rev=379810view=rev More comments inline... On 23.02.2006 07:02:33 Karl Roberts wrote: Hi I built a URIResolver that reads URL's like: servlet-context:/WEB-INF/metric.xml And it works fine, however when it encounters a URL that doesn't match the servlet-context scheme I return null. That's correct IMO. It's what I did. However I then get an NullPointerException Caused by: javax.xml.transform.TransformerException: java.lang.NullPointerException at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform (T ransformerImpl.java:647) at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform (T ransformerImpl.java:279) Hmm, I don't get these with my implementation. TransformerException is not the real exception. Look further down in the stack trace where you should find the right place where the exception occurred. The above doesn't really help. Setting an exception breakpoint for NullPointerException will also be useful. I do return null from my URIResolver in the cases where the scheme doesn't match the one I'm after, and FOURIResolver kicks in, but it never seems to come back to my URIResolver. Should I instead delegate to FOURIResolver rather than return null? No, I don't think so. There must be something else that's wrong. Can you try my implementation instead? http://svn.apache.org/repos/asf/xmlgraphics/fop/trunk/src/java/org/apach e/fop/servlet/ServletContextURIResolver.java snip/ Jeremias Maerki - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] NOTICE This e-mail and any attachments are confidential and may contain copyright material of Macquarie Bank or third parties. If you are not the intended recipient of this email you should not read, print, re-transmit, store or act in reliance on this e-mail or any attachments, and should destroy all copies of them. Macquarie Bank does not guarantee the integrity of any emails or any attached files. The views or opinions expressed are the author's own and may not reflect the views or opinions of Macquarie Bank. - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
RE: SOLVED - sort of Re how to embed a font programatically
Quick note, I changed the AgentHelper.setFOUserAgent(FOUserAgent foUserAgent) method to: public void setFOUserAgent(FOUserAgent foUserAgent) { synchronized (tlAgent) { tlAgent.set(foUserAgent); } } So that it is set every time a new Fop is constructed, to prevent any issues with the FOUserAgent (which contains a URIReader, that may contain a reference to the ServletContext, if using ServletContextURIResolver) from going stale. Karl -Original Message- From: Karl Roberts Sent: Monday, 27 February 2006 9:12 AM To: fop-users@xmlgraphics.apache.org Subject: RE: SOLVED - sort of Re how to embed a font programatically Hi Jeremias, Thanks for the update to Trunk, Your code was a bit tidier than mine, but did the same thing, However I still got the NullPointerException. The crux of the problem was that The URIReader was only being used to resolve URI's for Images in the XSLT to transform my XML to XSL-FO. It was not being used to resolve the URI of the font information passed in via the fopconfig.xml file. I traced the null pointer to a line in the createFont(String path) method of FontReader:- parser.parse(path); The javadoc for XMLReader.parse(String systemID) states that: If the system identifier is a URL, it must be fully resolved by the application before it is passed to the parser. However because it had not gon through the ServletContextURIResolver the String passed in was still like servet-context:///WEB-INF/fontinfo.xml. What would have been nice was the ability to inject a FontReader in the same way as URIReader can be injected into the FOUserAgent before it is passed to the Fop constructor, but I realised that the path should always be fully resolved and if a custom URIReader is injected, then we should use the FOUserAgent.resolveURI(String path) method to do it. I solved the problem (comments welcome) by createing a ThreadLocal Singleton (to attempt to avoid threading issues when used within a servlet) called AgentHelper that is initialised in the Fop Constructor:- /** modified Fop constructor **/ public Fop(String outputFormat, FOUserAgent ua) { this.outputFormat = outputFormat; foUserAgent = ua; if (foUserAgent == null) { foUserAgent = new FOUserAgent(); } boolean setOK = AgentHelper.getInstance().setFOUserAgent(foUserAgent); } And edited the FontReder.createFont(String path) method as follows, so that it uses the URIReader on the path first: /** Modified FontReader.createFont method **/ private void createFont(String path) throws FOPException { XMLReader parser = null; try { final SAXParserFactory factory = javax.xml.parsers.SAXParserFactory.newInstance(); factory.setNamespaceAware(true); parser = factory.newSAXParser().getXMLReader(); } catch (Exception e) { throw new FOPException(e); } if (parser == null) { throw new FOPException(Unable to create SAX parser); } try { parser.setFeature(http://xml.org/sax/features/namespace-prefixes;, false); } catch (SAXException e) { throw new FOPException(You need a SAX parser which supports SAX version 2, e); } parser.setContentHandler(this); try { // *** TODO KARL Feature improvment to FOP once in FOPTrunk, remove from here //parser.parse(path); FOUserAgent foUserAgent=AgentHelper.getInstance().getFOUserAgent(); Source s =foUserAgent.resolveURI(path); if(s!=null s instanceof StreamSource) { InputSource is; StreamSource ss = (StreamSource) s; is=new InputSource(ss.getInputStream()); parser.parse(is); } else { parser.parse(path); } // *** TODO End KARL Feature } catch (SAXException e) { throw new FOPException(e); } catch (IOException e) { throw new FOPException(e); } } And here is the AgentHelper Singleton:- import org.apache.fop.apps.FOUserAgent; public class AgentHelper { private static AgentHelper singleton = new AgentHelper(); private AgentHelper() { // Exists only to defeat instantiation. } private static class ThreadLocalFOUserAgent extends ThreadLocal {} private ThreadLocalFOUserAgent tlAgent = new ThreadLocalFOUserAgent(); public static AgentHelper getInstance() { return singleton; //no syncronization needed as statically initialised } public FOUserAgent getFOUserAgent() { synchronized (tlAgent
Re: Re how to embed a font programatically
Have you seen my other post? I've implemented exactly what I proposed to you and put it in FOP Trunk: http://svn.apache.org/viewcvs?rev=379810view=rev More comments inline... On 23.02.2006 07:02:33 Karl Roberts wrote: Hi I built a URIResolver that reads URL's like: servlet-context:/WEB-INF/metric.xml And it works fine, however when it encounters a URL that doesn't match the servlet-context scheme I return null. That's correct IMO. It's what I did. However I then get an NullPointerException Caused by: javax.xml.transform.TransformerException: java.lang.NullPointerException at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(T ransformerImpl.java:647) at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(T ransformerImpl.java:279) Hmm, I don't get these with my implementation. TransformerException is not the real exception. Look further down in the stack trace where you should find the right place where the exception occurred. The above doesn't really help. Setting an exception breakpoint for NullPointerException will also be useful. I do return null from my URIResolver in the cases where the scheme doesn't match the one I'm after, and FOURIResolver kicks in, but it never seems to come back to my URIResolver. Should I instead delegate to FOURIResolver rather than return null? No, I don't think so. There must be something else that's wrong. Can you try my implementation instead? http://svn.apache.org/repos/asf/xmlgraphics/fop/trunk/src/java/org/apache/fop/servlet/ServletContextURIResolver.java snip/ Jeremias Maerki - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
RE: Re how to embed a font programatically
Hi I built a URIResolver that reads URL's like: servlet-context:/WEB-INF/metric.xml And it works fine, however when it encounters a URL that doesn't match the servlet-context scheme I return null. However I then get an NullPointerException Caused by: javax.xml.transform.TransformerException: java.lang.NullPointerException at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(T ransformerImpl.java:647) at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(T ransformerImpl.java:279) I do return null from my URIResolver in the cases where the scheme doesn't match the one I'm after, and FOURIResolver kicks in, but it never seems to come back to my URIResolver. Should I instead delegate to FOURIResolver rather than return null? Cheers Karl -Original Message- From: Jeremias Maerki [mailto:[EMAIL PROTECTED] Sent: Tuesday, 21 February 2006 8:17 PM To: fop-users@xmlgraphics.apache.org Subject: Re: Re how to embed a font programatically I haven't done this from outside FOP, yet, but I can give you a suggestion that I'd prefer in your case: Write a URIResolver implementation that returns StreamSource instances for specific URIs. You can take FOURIResolver as an example for how to do that. You can then set the URIResolver instance on the FOUserAgent using setURIResolver(). This allows you to specify the font URLs like this: servlet-context:/WEB-INF/metric.xml In your URIResolver you simply check if the URI starts with servlet-context: and extract the path. You then simply construct a StreamSource giving it the InputStream returned by getResourceAsStream (). If a URI doesn't start with the above prefix just return null and the default URIResolver will kick in. The clue about all this is that you have to do less FOP-hacking and instead use the normal configuration mechanism. It should only take 30 minutes to hack. I hope that helps. On 21.02.2006 03:41:01 Karl Roberts wrote: Hi, Did you ever manage to do this? I need to do something similar because my embedded FOP is running in a Webapp and the font metric file and the TTF file are hidden inside the WEB-INF directory and so the metric-url and embed-url in my fop-config is no good (even if they were accessible via a URL I don't know the hostname or context path until runtime) What would be really nice is someway to pass the fontMetric and TTF file to the Renderer as InputSource (or InputStream). This way I can get the font files from the hidden WEB-INF dir using InputStream fontmetric = serve.servlet.getServletContext().getResourceAsStream(/WEB-INF/metric .x ml); InputStream embed = serve.servlet.getServletContext().getResourceAsStream(/WEB-INF/font.T TF ); Renderer myRenderer = new PDFRenderer(); FontInfo myFontInfo = new FontInfo(); // method needed ...(ahem) myFontInfo.addFont(FontName, FontStyle, FontWeight, fontmetric, embed); myRenderer.setupFontInfo(myFontInfo); userAgent.setRendererOverride(myRenderer); Am I on the right track? Has anyone done this (or better) and mind sharing the code? Cheers Karl On 2006-01-26 16:22:42 Jeremias Maerki wrote: Looking at the source code, you'd need to do the following: - Subclass the Renderer implementation (ex. PDFRenderer) so you gain access to the protected fontList member variable. - Fill the fontList variable much like FontSetup.buildFontListFromConfiguration() does. This code will need to run before you start the rendering run or at least before PrintRenderer.setupFontInfo() is called. - Instantiate your subclassed Renderer yourself and set it on the FOUserAgent using setRendererOverride(). Have fun! On 26.01.2006 16:59:17 Stefan Burkard wrote: hi fop-users i know i can use a custom font by building an xml-file with it's kerning-values and configuring a font definition in the user-config-file. but how can i include the font programatically? i don't like to have a user-config-file at all. i found examples to set the font-directory or base-directory programatically, but i didn't found an example for configuring fonts directly in java. can anybody help me? thanks stefan Jeremias Maerki - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] NOTICE This e-mail and any attachments are confidential and may contain copyright material of Macquarie Bank or third parties. If you are not the intended recipient of this email you should not read, print, re-transmit, store or act in reliance on this e-mail or any attachments, and should destroy all copies of them. Macquarie Bank does not guarantee the integrity of any emails or any attached files. The views or opinions expressed are the author's own and may not reflect the views or opinions of Macquarie Bank
Re: Re how to embed a font programatically
I haven't done this from outside FOP, yet, but I can give you a suggestion that I'd prefer in your case: Write a URIResolver implementation that returns StreamSource instances for specific URIs. You can take FOURIResolver as an example for how to do that. You can then set the URIResolver instance on the FOUserAgent using setURIResolver(). This allows you to specify the font URLs like this: servlet-context:/WEB-INF/metric.xml In your URIResolver you simply check if the URI starts with servlet-context: and extract the path. You then simply construct a StreamSource giving it the InputStream returned by getResourceAsStream (). If a URI doesn't start with the above prefix just return null and the default URIResolver will kick in. The clue about all this is that you have to do less FOP-hacking and instead use the normal configuration mechanism. It should only take 30 minutes to hack. I hope that helps. On 21.02.2006 03:41:01 Karl Roberts wrote: Hi, Did you ever manage to do this? I need to do something similar because my embedded FOP is running in a Webapp and the font metric file and the TTF file are hidden inside the WEB-INF directory and so the metric-url and embed-url in my fop-config is no good (even if they were accessible via a URL I don't know the hostname or context path until runtime) What would be really nice is someway to pass the fontMetric and TTF file to the Renderer as InputSource (or InputStream). This way I can get the font files from the hidden WEB-INF dir using InputStream fontmetric = serve.servlet.getServletContext().getResourceAsStream(/WEB-INF/metric.x ml); InputStream embed = serve.servlet.getServletContext().getResourceAsStream(/WEB-INF/font.TTF ); Renderer myRenderer = new PDFRenderer(); FontInfo myFontInfo = new FontInfo(); // method needed ...(ahem) myFontInfo.addFont(FontName, FontStyle, FontWeight, fontmetric, embed); myRenderer.setupFontInfo(myFontInfo); userAgent.setRendererOverride(myRenderer); Am I on the right track? Has anyone done this (or better) and mind sharing the code? Cheers Karl On 2006-01-26 16:22:42 Jeremias Maerki wrote: Looking at the source code, you'd need to do the following: - Subclass the Renderer implementation (ex. PDFRenderer) so you gain access to the protected fontList member variable. - Fill the fontList variable much like FontSetup.buildFontListFromConfiguration() does. This code will need to run before you start the rendering run or at least before PrintRenderer.setupFontInfo() is called. - Instantiate your subclassed Renderer yourself and set it on the FOUserAgent using setRendererOverride(). Have fun! On 26.01.2006 16:59:17 Stefan Burkard wrote: hi fop-users i know i can use a custom font by building an xml-file with it's kerning-values and configuring a font definition in the user-config-file. but how can i include the font programatically? i don't like to have a user-config-file at all. i found examples to set the font-directory or base-directory programatically, but i didn't found an example for configuring fonts directly in java. can anybody help me? thanks stefan Jeremias Maerki - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
RE: Re how to embed a font programatically
Hi Jeremias, Cheers for that. My main issue is that I wanted to as little hacking of the underlying FOP as possible so that I can keep all my stuff in separate extended classes (less source control issues) and do it as fast as possible ;-) Being quite new to FOP I am unaware of some of the design philosopies. Injecting my own URIResolver is a much nicer solution than what I was going to do. So thanks again Karl -Original Message- From: Jeremias Maerki [mailto:[EMAIL PROTECTED] Sent: Tuesday, 21 February 2006 8:17 PM To: fop-users@xmlgraphics.apache.org Subject: Re: Re how to embed a font programatically I haven't done this from outside FOP, yet, but I can give you a suggestion that I'd prefer in your case: Write a URIResolver implementation that returns StreamSource instances for specific URIs. You can take FOURIResolver as an example for how to do that. You can then set the URIResolver instance on the FOUserAgent using setURIResolver(). This allows you to specify the font URLs like this: servlet-context:/WEB-INF/metric.xml In your URIResolver you simply check if the URI starts with servlet-context: and extract the path. You then simply construct a StreamSource giving it the InputStream returned by getResourceAsStream (). If a URI doesn't start with the above prefix just return null and the default URIResolver will kick in. The clue about all this is that you have to do less FOP-hacking and instead use the normal configuration mechanism. It should only take 30 minutes to hack. I hope that helps. On 21.02.2006 03:41:01 Karl Roberts wrote: Hi, Did you ever manage to do this? I need to do something similar because my embedded FOP is running in a Webapp and the font metric file and the TTF file are hidden inside the WEB-INF directory and so the metric-url and embed-url in my fop-config is no good (even if they were accessible via a URL I don't know the hostname or context path until runtime) What would be really nice is someway to pass the fontMetric and TTF file to the Renderer as InputSource (or InputStream). This way I can get the font files from the hidden WEB-INF dir using InputStream fontmetric = serve.servlet.getServletContext().getResourceAsStream(/WEB-INF/metric .x ml); InputStream embed = serve.servlet.getServletContext().getResourceAsStream(/WEB-INF/font.T TF ); Renderer myRenderer = new PDFRenderer(); FontInfo myFontInfo = new FontInfo(); // method needed ...(ahem) myFontInfo.addFont(FontName, FontStyle, FontWeight, fontmetric, embed); myRenderer.setupFontInfo(myFontInfo); userAgent.setRendererOverride(myRenderer); Am I on the right track? Has anyone done this (or better) and mind sharing the code? Cheers Karl On 2006-01-26 16:22:42 Jeremias Maerki wrote: Looking at the source code, you'd need to do the following: - Subclass the Renderer implementation (ex. PDFRenderer) so you gain access to the protected fontList member variable. - Fill the fontList variable much like FontSetup.buildFontListFromConfiguration() does. This code will need to run before you start the rendering run or at least before PrintRenderer.setupFontInfo() is called. - Instantiate your subclassed Renderer yourself and set it on the FOUserAgent using setRendererOverride(). Have fun! On 26.01.2006 16:59:17 Stefan Burkard wrote: hi fop-users i know i can use a custom font by building an xml-file with it's kerning-values and configuring a font definition in the user-config-file. but how can i include the font programatically? i don't like to have a user-config-file at all. i found examples to set the font-directory or base-directory programatically, but i didn't found an example for configuring fonts directly in java. can anybody help me? thanks stefan Jeremias Maerki - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] NOTICE This e-mail and any attachments are confidential and may contain copyright material of Macquarie Bank or third parties. If you are not the intended recipient of this email you should not read, print, re-transmit, store or act in reliance on this e-mail or any attachments, and should destroy all copies of them. Macquarie Bank does not guarantee the integrity of any emails or any attached files. The views or opinions expressed are the author's own and may not reflect the views or opinions of Macquarie Bank. - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re how to embed a font programatically
Hi, Did you ever manage to do this? I need to do something similar because my embedded FOP is running in a Webapp and the font metric file and the TTF file are hidden inside the WEB-INF directory and so the metric-url and embed-url in my fop-config is no good (even if they were accessible via a URL I don't know the hostname or context path until runtime) What would be really nice is someway to pass the fontMetric and TTF file to the Renderer as InputSource (or InputStream). This way I can get the font files from the hidden WEB-INF dir using InputStream fontmetric = serve.servlet.getServletContext().getResourceAsStream(/WEB-INF/metric.x ml); InputStream embed = serve.servlet.getServletContext().getResourceAsStream(/WEB-INF/font.TTF ); Renderer myRenderer = new PDFRenderer(); FontInfo myFontInfo = new FontInfo(); // method needed ...(ahem) myFontInfo.addFont(FontName, FontStyle, FontWeight, fontmetric, embed); myRenderer.setupFontInfo(myFontInfo); userAgent.setRendererOverride(myRenderer); Am I on the right track? Has anyone done this (or better) and mind sharing the code? Cheers Karl On 2006-01-26 16:22:42 Jeremias Maerki wrote: Looking at the source code, you'd need to do the following: - Subclass the Renderer implementation (ex. PDFRenderer) so you gain access to the protected fontList member variable. - Fill the fontList variable much like FontSetup.buildFontListFromConfiguration() does. This code will need to run before you start the rendering run or at least before PrintRenderer.setupFontInfo() is called. - Instantiate your subclassed Renderer yourself and set it on the FOUserAgent using setRendererOverride(). Have fun! On 26.01.2006 16:59:17 Stefan Burkard wrote: hi fop-users i know i can use a custom font by building an xml-file with it's kerning-values and configuring a font definition in the user-config-file. but how can i include the font programatically? i don't like to have a user-config-file at all. i found examples to set the font-directory or base-directory programatically, but i didn't found an example for configuring fonts directly in java. can anybody help me? thanks stefan NOTICE This e-mail and any attachments are confidential and may contain copyright material of Macquarie Bank or third parties. If you are not the intended recipient of this email you should not read, print, re-transmit, store or act in reliance on this e-mail or any attachments, and should destroy all copies of them. Macquarie Bank does not guarantee the integrity of any emails or any attached files. The views or opinions expressed are the author's own and may not reflect the views or opinions of Macquarie Bank. - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: how to embed a font programatically
Looking at the source code, you'd need to do the following: - Subclass the Renderer implementation (ex. PDFRenderer) so you gain access to the protected fontList member variable. - Fill the fontList variable much like FontSetup.buildFontListFromConfiguration() does. This code will need to run before you start the rendering run or at least before PrintRenderer.setupFontInfo() is called. - Instantiate your subclassed Renderer yourself and set it on the FOUserAgent using setRendererOverride(). Have fun! On 26.01.2006 16:59:17 Stefan Burkard wrote: hi fop-users i know i can use a custom font by building an xml-file with it's kerning-values and configuring a font definition in the user-config-file. but how can i include the font programatically? i don't like to have a user-config-file at all. i found examples to set the font-directory or base-directory programatically, but i didn't found an example for configuring fonts directly in java. can anybody help me? thanks stefan Jeremias Maerki - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: how to embed a font programatically
Hi Stefan I'm using my own fonts and the userconfig file. All fonts, metrics and configuration are stored in my web application. The bug with the base URL is solved in svn trunk. The application works just fine. Unfortunately I can't help you with with the configuration of fonts. Cheers Uwe Stefan Burkard wrote: hi fop-users i know i can use a custom font by building an xml-file with it's kerning-values and configuring a font definition in the user-config-file. but how can i include the font programatically? i don't like to have a user-config-file at all. i found examples to set the font-directory or base-directory programatically, but i didn't found an example for configuring fonts directly in java. can anybody help me? thanks stefan - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] begin:vcard fn:Uwe Klosa n:Klosa;Uwe org:Uppsala University;Electronic Publishing Centre adr:;;;Uppsala;;75120;Sweden email;internet:[EMAIL PROTECTED] tel;work:+46 (0)18 471 7658 url:http://publications.uu.se/epcentre version:2.1 end:vcard - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]