Using system fonts with iText

I'm trying to generate PDF document in Java using iText. link

But I also want to give users an opportunity to choose which font to use for the document. There are many fonts, installed in the system, I can list them using

GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();

but when I try to pass font names to BaseFont constructor directly

BaseFont.createFont(s, BaseFont.IDENTITY_H, true);

I get an exception like

com.lowagie.text.DocumentException: Font 'Abyssinica SIL' with 'Identity-H' is not recognized.

Another option is to pass to the BaseFont the path to the font file (either stored inside jar or somewhere on the system), but in the first case I have to deploy all the fonts with my application, and in the second case I have to think of a way of getting system font files locations. As far as I know, Java puts a layer of abstraction over fonts - public API doesn't know anything of paths, and usage of private API (something like FontManager) is discouraged.

Yet another option is to use constants, declared in BaseFont , but that gives only 4 fonts (Courier, Helvetica, Symbol and Times Roman).

Is there a way to use system fonts in PDFs, generated with iText without deploying them with application and using workarounds like FontManager?

Upvotes: 1

Views: 1600

Answers (1)

Lonzak
Lonzak

Reputation: 9816

I had the exact same problem:

How can I use the (operating) system fonts in the iText pdf library?

First approach (didn' work)

In Java I can iterate through the fonts like this:

java.awt.Font[] systemFonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
for (java.awt.Font awtSystemFont : systemFonts) {
  //list of java system fonts
}

The pdf libraries DefaultFontMapper class seem to have a suitable method:

DefaultFontMapper fontmapper = new DefaultFontMapper();
fontmapper.awtToPdf(awtSystemFont);

However this method only returns the base14 fonts and as a default usually Helvetica is returned. But I need e.g. Arial, Roboto and others.

Second approach (didn't work)

Then I found that I could also implement my own FontMapper which loads the AWT fonts however there is no cross platform way to access the *.ttf files itself. One needs to access restricted packages (like com.sun) or it only works under specific operating systems.

Third approach (did work!)

//this registers the font dirs across platforms
FontFactory.registerDirectories();
Font itextFont = FontFactory.getFont("Arial",12);
//if the basefont is needed, access it like this:    
itextFont.getBaseFont();

Upvotes: 0

Related Questions