Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load a font from JAR for FOP

I have a TTF font in fonts directory in the JAR with my application.

 myapp.jar /
     fop /
        config.xml
        font.ttf

I create my FOP this way:

    FopFactory fopFactory = FopFactory.newInstance();
    fopFactory.setStrictValidation(false);
    fopFactory.setUserConfig(getClasspathFile("/fop/config.xml"));
    FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
   ...

How do I configure config.xml to embeddd font.ttf in the PDF file I am rendering?

like image 750
Luce Ian Avatar asked Jul 19 '13 11:07

Luce Ian


People also ask

How to add a JAR file to FOP?

The JAR files can be added to fop by providem them in the classpath, e.g. copying them into the lib/ directory. The PostScript renderer does not yet support TrueType fonts, but can embed Type 1 fonts.The font is simply embedded into the PDF file, it is not converted.

Why does FOP add a prefix to the FontName?

When FOP embeds a font, it adds a prefix to the fontname to ensure that the name will not match the fontname of an installed font. This is helpful with older versions of Acrobat Reader that preferred installed fonts over embedded fonts. When embedding PostScript fonts, the entire font is always embedded.

Can I add custom fonts to FOP renderers?

Other renderers (like AFP) support other font formats. Details in this case can be found on the page about output formats. In earlier FOP versions, it was always necessary to create an XML font metrics file if you wanted to add a custom font.

What is font cache in Apache FOP?

The font cache¶. Apache FOP maintains a cache file that is used to speed up auto-detection. This file is usually found in the ".fop" directory under the user's home directory. It's called "fop-fonts.cache". When the user's home directory is not writable, the font cache file is put in the directory for temporary files.


1 Answers

it seems that my post is too late, but may be it'll be useful for the others. [java 8, fop 2.1]

import lombok.SneakyThrows;
...
        @SneakyThrows
            private FopFactory getFopFactory(){
                InputStream fopConfigStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("/fop/config.xml");
                FopFactoryBuilder builder = new FopFactoryBuilder(new File(".").toURI(), new CustomPathResolver());
                FopFactory factory = builder.setConfiguration(new DefaultConfigurationBuilder().build(fopConfigStream)).build();
                fopConfigStream.close();
                return factory;
            }
    ...
        private static final class CustomPathResolver implements ResourceResolver {
            @Override
            public OutputStream getOutputStream(URI uri) throws IOException {
                return Thread.currentThread().getContextClassLoader().getResource(uri.toString()).openConnection()
                        .getOutputStream();
            }

            @Override
            public Resource getResource(URI uri) throws IOException {
                InputStream inputStream = ClassLoader.getSystemResourceAsStream("fop/" + FilenameUtils.getName(uri));
                return new Resource(inputStream);
            }
        }

config.xml:

<fop version="1.0">
    <renderers>
        <renderer mime="application/pdf">
            <fonts>
              <font kerning="yes" embed-url="font.ttf" embedding-mode="subset">
                <font-triplet name="Font name" style="normal" weight="normal"/>
              </font>
            </fonts>
        </renderer>
    </renderers>
</fop>
like image 139
Mark Sorokin Avatar answered Oct 21 '22 12:10

Mark Sorokin