1

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?

  • (1.) When I see my name (lowagie) in an exception, I *know* that you're using a version of iText that is no longer supported, (2.) The message "Abyssinica SIL is not recognized" means that you didn't register the font with iText. You need to register all the fonts you're using. This doesn't happen automatically because it's a costly operation from a CPU point of view (and we don't want to punish people who only use a limited set of fonts). – Bruno Lowagie Nov 17 '15 at 05:53
  • @Дмитрий Карякин, Did you resolve this issue? Have the same problem – StasKolodyuk Jun 02 '16 at 09:23
  • Nope, we decided to use only one font, and anyway I left the company soon. As far as I remember, you need to find a way to tell the PDF reader where it should look for fonts. The common approach is to include the font file itself. In order to do so you have to read ttf file itself from resource or file system. Your options are either specify font folder path for you application and scan it, or include all the fonts you need in resources. Maybe the best option is to choose a few fonts your users are likely to use, load and keep them in memory. – Дмитрий Карякин Jun 03 '16 at 21:38

1 Answers1

0

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();
Lonzak
  • 9,334
  • 5
  • 57
  • 88