Package net.sf.jasperreports.engine.fonts

Provides support for font extensions.

The Font Extension Point

Among the various extension points that JasperReports exposes, this one allows users to make use of fonts that are not available to the JVM at runtime in normal circumstances.

Usually, in order to make a font file available to the JVM, one would need to install that font file into the system, or make some configuration changes in the local JVM. But if the application ends up being deployed on some other machine, the same font file installation process has to be performed on that machine as well.

When designing reports, we are immediately faced with the selection of fonts to be used by the various text fields present in the report template. Using fonts that are available only on the local JVM where we design and test our reports poses the risk of those fonts not being available on the system where the reports are actually generated at runtime.

When specified fonts are missing on a system, the JVM uses some default fonts as on-the-fly replacements and these might have totally different properties and font metrics, producing various side effects, including but not limited to chunks of text being cut from the generated output.

This is why it is so important for an application to control and make sure that the fonts used in its reports are available at runtime on the machines on which the application is running.

The best way to control fonts in JasperReports is to provide the font files as extensions to the library. Basically, this involves putting various Font files (such as True Type, Open Type, SVG or Web Open Font Format) in a JAR file, together with an XML file that describes the content of the JAR and the various relationships between the fonts and the locales.

JasperReports raises a JRFontNotFoundException in the case where the font used inside a report template is not available to the JVM as either as a system font or a font coming from a JR font extension. This ensure that all problems caused by font metrics mismatches are avoided and we have an early warning about the inconsistency.

However, for backward compatibility reasons, this font runtime validation can be turned off using the net.sf.jasperreports.awt.ignore.missing.font configuration property, which can be employed either globally or at report level.

The font extension point in JasperReports is exposed as the FontFamily public interface. Each font family is made out of 4 font faces: normal, bold, italic and bolditalic. None of them is required in a font family, but when they are all missing, then the name of the font family should be the name of an existing font face, already installed on the machine. Font faces are described by the FontFace interface. Besides the font faces, a font family also supports certain locales and tells if it is able to simulate the bold style and the italic style in PDF export, in case the corresponding font faces are missing from its declaration.

JasperReports is shipped with convenience implementations for the above mentioned interfaces. The SimpleFontFamily is the default implementation of the FontFamily interface. This works with the SimpleFontFace default implementation of the font face.

The best way to deploy font files as extensions is to rely on the font extension registry factory shipped with JasperReports and make use of the default font interfaces.

Simple Font Extension Example

The samples shipped with the JasperReports project distribution package under the /demo/samples folder make use of two font families called DejaVu Sans and DejaVu Serif. These are open source fonts from the http://dejavu-fonts.org project and are made available to the samples as a font extension.

This font extension is found in the /ext/fonts folder of the JasperReports project distribution package and consists of the following files:

jasperreports_extension.properties

This file is required by the JasperReports extension mechanism and describes the content of any given extension. The first line in this particular properties file specifies that the built-in font extension registry factory is used by the current extension:

 net.sf.jasperreports.extension.registry.factory.simple.font.families=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory
 net.sf.jasperreports.extension.simple.font.families.dejavu=net/sf/jasperreports/fonts/fonts.xml
 
The second line gives the name of the XML file required by this font extension factory, containing the font family and font set definitions.

This XML file contains the elements that are going to be loaded by the font extension registry factory. As mentioned earlier, the font extension point in JasperReports is expecting font families, so the elements in our XML file are converted into instances of the convenience SimpleFontFamily implementation of the FontFamily interface and introduce two font families: the DejaVu Sans and the DejaVu Serif.

 <fontFamily name="DejaVu Sans">
   <normal>net/sf/jasperreports/fonts/dejavu/DejaVuSans.ttf</normal>
   <bold>net/sf/jasperreports/fonts/dejavu/DejaVuSans-Bold.ttf</bold>
   <italic>net/sf/jasperreports/fonts/dejavu/DejaVuSans-Oblique.ttf</italic>
   <boldItalic>net/sf/jasperreports/fonts/dejavu/DejaVuSans-BoldOblique.ttf</boldItalic>
   <pdfEncoding>Identity-H</pdfEncoding>
   <pdfEmbedded>true</pdfEmbedded>
   <exportFonts>
     <export key="net.sf.jasperreports.html">'DejaVu Sans', Arial, Helvetica, sans-serif</export>
   </exportFonts>
 </fontFamily>
 
 <fontFamily name="DejaVu Serif">
   <normal>net/sf/jasperreports/fonts/dejavu/DejaVuSerif.ttf</normal>
   <bold>net/sf/jasperreports/fonts/dejavu/DejaVuSerif-Bold.ttf</bold>
   <italic>net/sf/jasperreports/fonts/dejavu/DejaVuSerif-Italic.ttf</italic>
   <boldItalic>net/sf/jasperreports/fonts/dejavu/DejaVuSerif-BoldItalic.ttf</boldItalic>
   <pdfEncoding>Identity-H</pdfEncoding>
   <pdfEmbedded>true</pdfEmbedded>
   <exportFonts>
     <export key="net.sf.jasperreports.html">'DejaVu Serif', 'Times New Roman', Times, serif</export>
   </exportFonts>
 </fontFamily>
 
Notice how font families are specifying a name and their different faces. The name and the normal face are both required, while the other properties are optional.

The name of the family is required because this is the value that gets used as the fontName attribute of a text element or a style in the report template. The fontName together with the isBold and isItalic attributes of the text field or style in the report help to locate and load the appropriate font face from the family. In case a particular font face is not present or declared in the family whose name was used, then the normal font face is used instead and this makes the normal face mandatory in a font family.

Font files usually support only some languages and this is why the font families can specify the list of locales that they support. In the example above, no locale was specified, meaning that the DejaVu Sans and the DejaVu Serif families would apply to all locales (which is not true, but the JasperReports samples that use this font extension do not make use of languages that are not supported by this font families, so we did not bother to filter on supported locales).

However, locale support in font families is extremely important in cases where font families having the same name are made of different TTF files supporting different locales.

A very good example is of people using the same fontName value inside their reports that sometimes are generated in Chinese and other times in Japanese. They would use a set of TTF files that support Chinese and another set of TTF files that support Japanese. With them, they would create two font families having the same fontName name, and specify Chinese as supported locale for the first one and Japanese for the second. This way, depending on the runtime locale, the appropriate font family would be selected, with the appropriate TTF files for that locale, although at design time the fontName attribute was the same for all text fields, regardless of locale.

Below is the extract from a fonts.xml file that would declare a DejaVu Serif font family supporting only English and German:

 <fontFamily name="DejaVu Sans">
   <normal>net/sf/jasperreports/fonts/dejavu/DejaVuSans.ttf</normal>
   <bold>net/sf/jasperreports/fonts/dejavu/DejaVuSans-Bold.ttf</bold>
   <italic>net/sf/jasperreports/fonts/dejavu/DejaVuSans-Oblique.ttf</italic>
   <boldItalic>net/sf/jasperreports/fonts/dejavu/DejaVuSans-BoldOblique.ttf</boldItalic>
   <pdfEncoding>Identity-H</pdfEncoding>
   <pdfEmbedded>true</pdfEmbedded>
   <exportFonts>
     <export key="net.sf.jasperreports.html">'DejaVu Sans', Arial, Helvetica, sans-serif</export>
   </exportFonts>
   <!--
   <locales>
     <locale>en_US</locale>
     <locale>de_DE</locale>
   </locales>
   -->
 </fontFamily>
 
For more details about deploying fonts as extensions, you can take a look at the /demo/samples/fonts sample provided with the JasperReports project distribution package, which adds one more font extension for another open source font called Lobster Two.

Related Documentation

JasperReports Tutorial
See Also:
JRFontNotFoundException