'Not finding font Arial.ttf with apache fop 1.0

I use:

  • Apache fop 1.0
  • Java

I need to handle with special characters which unicode is higher than u0100. The target font I should use is Arial. As I cannot expect Arial is present on the target platform (eg. Linux), I embedded an Arial.ttf in my jar. My actual config-file looks like this:

<fop ...>
<!-- Base URL for resolving relative URLs -->
<base>./</base>

<!-- Font Base URL for resolving relative font URLs -->
<font-base>./</font-base>

<renderers>
    <renderer mime="application/pdf">
        <fonts>

            <font kerning="yes" embed-url="arial.ttf" encoding-mode="auto">
                <font-triplet name="Arial" style="normal" weight="normal"/>
                <font-triplet name="ArialMT" style="normal" weight="normal"/>
            </font>

            <!--<directory>C:/Windows/Fonts</directory>-->

        </fonts>
        <auto-detect/>
    </renderer>
 ...
</fop>

Doing it this way I get an error loading my config-file to fop:

org.apache.fop.apps.FOPException: Failed to resolve font with embed-url 'arial.ttf'

The only way I managed to get it work until now was to hardcode the folder path into the config file:

            <font kerning="yes" embed-url="C:/myapp/arial.ttf" encoding-mode="auto">
                <font-triplet name="Arial" style="normal" weight="normal"/>
                <font-triplet name="ArialMT" style="normal" weight="normal"/>
            </font>

But obviously this cannot be the solution!

Using the "directory" tag whould work on Windows, just because you have Arial there. But as mentioned above it must also run on Linux, Macs, etc.

The "auto-detect" tag didn't work either (even not on Windows) - and isn't a solution as I cannot expect the target platform having Arial installed.

Any suggestions to solve this?



Solution 1:[1]

I finally found the answer. See: https://web.archive.org/web/20120831233158/http://www.publicstaticfinal.de/2011/01/26/fop-embedding-fonts-from-classpath

The solution is to add an own URIResolver to the fopFactory.

Solution 2:[2]

This solution doesn't work for me. It is because ClassLoader.getSystemResourceAsStream(href); returns null.

I have found another solution but it has a different problem - if you have some other resources which you add to the FOP with the absolute system path (e.g. images selected by user), than your custom URIResolver is used either for them so they are resolved incorrectly.

If you want to correct these examples just mix them and you are getting working solution like this:

import java.io.InputStream;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import javax.xml.transform.stream.StreamSource;

public class ClasspathUriResolver implements URIResolver {

    @Override
    public Source resolve(String href, String base) throws TransformerException {
        Source source = null;
        InputStream inputStream = getClass().getResourceAsStream(href);
        if (inputStream != null) {
            source = new StreamSource(inputStream);
        }
        return source;
    }
}

Usage

[...]

FopFactory fopFactory = FopFactory.newInstance();

FOURIResolver uriResolver = (FOURIResolver) fopFactory.getURIResolver();
uriResolver.setCustomURIResolver(new ClasspathUriResolver());

[...]

Solution 3:[3]

You have <auto-detect/> outside the <fonts> tag. To solve our font problem we put <auto-detect/> inside the <fonts> tag. We don't use additional <font> configurations, but just use the system fonts detected with <auto-detect/>

Solution 4:[4]

Not sure if it's your problem but I found out that since some version relative paths don't work for in the Fop config file. For me, it worked if I either supplied an absolute path (starting with '/') or prefixed the path with 'file:' like 'file:.'.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Michał Stochmal
Solution 2 Knut Holm
Solution 3 user3665942
Solution 4 Alexandr Kára