2013-11-20 160 views
2

PDFBox提供了嵌入各種類型字體的機制。例如,它提供了PDTrueTypeFont.loadTTF(...),它可以接受一個TrueType(* .ttf)文件。使用PDFBox嵌入* .ttc字體

TrueType集合格式(* .ttc)在TrueType格式的擴展名中支持每個文件多個字體。

試圖加載一個* .ttc文件與PDTrueTypeFont.loadTTF()導致拋出一個IOException。

如何使用PDFBox將* .ttc文件中的一種或全部字體嵌入到PDF文檔中?

回答

2

PDF規範不允許將TrueType集合作爲嵌入字體。您需要從* .ttc中提取一個TTF格式的數據流並嵌入。

因爲它(和AFAIK)PDFBox不支持它本身;我用谷歌的 'sfntly' package.

快速和骯髒的解決方案:

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)); 
} 

FontFontFactorycom.google.typography.sfntly

Java代碼,但不保證100%正確;最近一直在Clojure工作....

+0

謝謝!看起來不錯。我可以輕鬆地從* .ttc文件中獲取字體名稱嗎?你碰巧知道,如果獲得的字體名字需要解析字體的其餘部分? –

+0

你*可以*輕鬆得到名字;但它並不完全「簡單」。你需要'getTable(Tag.name)'來獲得'NameTable'的一個實例。你可以用'.getNameEntry'從那裏訪問名字,但是你必須傳入適當的常量。這將使您能夠訪問字體的一系列「名稱」。你可能最安全的做法是迭代NameTable,並用'FontFamilyName'或'PreferredFamily'作爲它的'nameId'拉第一個條目。 – jgriego

+0

...不幸的是,是的;當你輕鬆地構建'Font's時,它會解析整個sfnt包裝器,但是如果你需要使用'FontFactory.loadFontsForBuilding'(它提供'Font.Builder'對象列表;你可以讓它解析* less *然後你可以在構建器對象上調用'.build()'來產生一個'Font'對象,你可以在其中調用。 – jgriego