Search code examples
javapdfboxtruetype

Embedding *.ttc fonts using PDFBox


PDFBox provides mechanisms to embed various types of fonts. For example, it provides PDTrueTypeFont.loadTTF(...), which can accept a TrueType (*.ttf) file.

The TrueType Collection format (*.ttc) supports multiple fonts per file, in an extension of the TrueType format.

Attempting to load a *.ttc file with PDTrueTypeFont.loadTTF() results in an IOException being thrown.

How does one embed one or all of the fonts in a *.ttc file into a PDF document, using PDFBox?


Solution

  • The PDF specification doesn't allow for TrueType collections as embedded fonts. You'll need to pull out a single TTF-format stream from the *.ttc and embed that.

    As it stands (and AFAIK) PDFBox doesn't support this by itself; I used Google's 'sfntly' package.

    Quick and dirty solution:

    FontFactory factory = FontFactory.getInstance();
    Font[] fonts = factory.loadFonts( ... ); // pulls every TTF out of TTC
    ArrayList<PDTrueTypeFont> pdf_fonts = new ArrayList<PDTrueTypeFont>();
    for( Font f : fonts ){
       // sfntly writes each font to a TTF stream
       ByteArrayOutputStream out = ByteArrayOutputStream();
       factory.serializeFont(f, out);
    
       // PDFBox reads the stream and embeds the font
       ByteArrayInputStream ttf_font_stream = ByteArrayInputStream(out.toByteArray());
       pdf_fonts.add(PDTrueTypeFont.loadTTF(document, ttf_font_stream));
    }
    

    Font and FontFactory are in com.google.typography.sfntly

    Java code not guaranteed to be 100% correct; been working in Clojure a lot lately....