Thursday, June 7, 2012

Font Extensions


One issue in a system that I work on that was kind of side stepped around for awhile is the issue of custom fonts in reports, specifically reports built with the Jasper Reports framework. For a while we were just building all our reports in a standard font which was included in the build so this worked fine.

However, when we build custom reports for customers, they sometimes want text to be in specific fonts to match their branding. This is a completely reasonable requirement, but we just needed a sure fire way to deal with it.

In past times we would just take the font and install it on the customer's server however this was brittle since as soon as you would move the customer to another server, it would break their custom reports. Also this approach was problematic in rendering the PDFs correctly on any machine.

So the best way is to just include the fonts in the build. Fortunately Jasper Reports includes something called font extensions that make this very easy. Basically you just put a properties file in the default package called "jasperreports_extension.properties" and Jasper will automatically find the file. This file just sets a couple properties and tells Jasper where to find the font XML configuration file.

Example jasperreports_extension.properties:


net.sf.jasperreports.extension.registry.factory.fonts=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory
net.sf.jasperreports.extension.simple.font.families.frsfamily=fonts/frsfontsfamily.xml

Next you create a "fonts" directory, place your True Type Format fonts in there, and create an XML file that configures the fonts.

Example XML font config file:

xml version="1.0" encoding="UTF-8"?>
<fontFamilies>

   <fontFamily name="NewsGothicBT-Roman">
       <normal>fonts/News Gothic.ttfnormal>
       <bold>fonts/News Gothic Bold.ttfbold>
       <pdfEmbedded>truepdfEmbedded>
   fontFamily>

   <fontFamily name="Planer">
       <normal>fonts/Planer_Reg.ttfnormal>
       <bold>fonts/planerdemibold.ttfbold>
       <pdfEmbedded>truepdfEmbedded>
   fontFamily>

fontFamilies>

Jasper reads the above XML and registers the fonts. Whenever the above font names are referenced in a report, the TTF fonts are used and embedded in the PDF itself (notice pdfEmbedded=true above) so that the PDF will be rendered correctly on any system that opens it.

So from now on whenever a custom font is needed, we just drop the TTF font files in the fonts directory, configure them in frsfontsfamily.xml and they are available everywhere.

Our next step might be to create a way to dynamically load fonts onto a live system allowing for more flexibility but for now we are happy with being able to include fonts in the build guaranteeing that they will be available and embedded in the PDFs.