Как избавиться от Helvetica в iText XMLWorker?
Мы используем iText для генерации PDF-файлов из кода Java, который в большинстве случаев работает довольно хорошо. Несколько дней назад мы начали генерировать PDF / A вместо обычных PDF-файлов, в которые нужно встроить все шрифты. ITextDocument
в основном сборка на заказPdfPTable
и другие классы, где мы напрямую контролируем шрифты. Все используемые шрифты создаются из файлов TTF, загруженных с помощью следующего кода - который работает просто отлично:
private BaseFont load(String path) {
try {
URL fontResource = PrintSettings.class.getResource(path);
if (fontResource == null) {
return null;
}
String fontPath = fontResource.toExternalForm();
BaseFont baseFont = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
baseFont.setSubset(true);
return baseFont;
}
catch (DocumentException ex) {
Logger.getLogger(PrintSettings.class).warn("...");
}
catch (IOException ex) {
Logger.getLogger(PrintSettings.class).warn("...");
}
return FontFactory.getFont(PrintSettings.FONT, "UTF-8", true, 8f, Font.NORMAL, PrintSettings.COLOR_TEXT).getBaseFont();
}
Теперь мы используем один конкретный тип содержимого в PDF, который генерируется из кода HTML. Мы используемXMLWorker
чтобы справиться с этой частью. Это работало просто отлично, если мы не встраивали шрифты. Но с PDF / A мыneed встроить все шрифты, и теперь мы боремся с неизвестным источникомHelvetica использование.
Мы пытались решить эту проблему с помощью нашего собственногоFontProvider класс как этот:
public class PrintFontProvider extends FontFactoryImp {
@Override
public Font getFont(String fontName, String encoding, boolean embedded, float size, int style, BaseColor color, boolean cached) {
// LiberationSans – http://de.wikipedia.org/wiki/Liberation_(Schriftart) – http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web
if (style == Font.NORMAL) return new Font(this.load("fonts/Liberation/LiberationSans-Regular.ttf"), size, Font.NORMAL, color);
if (style == Font.BOLD) return new Font(this.load("fonts/Liberation/LiberationSans-Bold.ttf"), size, Font.NORMAL, color);
if (style == Font.BOLDITALIC) return new Font(this.load("fonts/Liberation/LiberationSans-BoldItalic.ttf"), size, Font.NORMAL, color);
if (style == Font.ITALIC) return new Font(this.load("fonts/Liberation/LiberationSans-Italic.ttf"), size, Font.NORMAL, color);
return new Font(this.load("fonts/Liberation/LiberationSans-Regular.ttf"), size, style, color);
}
private BaseFont load(String path) { ... }
}
Это связано сXMLWorker
используя следующий код:
HtmlPipelineContext html = new HtmlPipelineContext(null);
html.setTagFactory(Tags.getHtmlTagProcessorFactory());
CSSResolver css = XMLWorkerHelper.getInstance().getDefaultCssResolver(true);
// We need to control the FontProdiver!
html.setCssAppliers(new CssAppliersImpl(new PrintFontProvider()));
Pipeline<?> pipeline = new CssResolverPipeline(css, new HtmlPipeline(html, new PdfWriterPipeline(this.document, writer)));
XMLWorker worker = new XMLWorker(pipeline, true);
XMLParser p = new XMLParser(worker);
p.parse(new ByteArrayInputStream(StringUtils.iTextHTML(string).getBytes()));
Большинство простых элементов HTML работают таким образом ... но есть некоторые, которые, кажется, игнорируют FontProvider и продолжают использоватьHelvetica который не будет встроен в PDF / A (у нас нет этого шрифта). Например<ol><li>...</li></ol>
использовать это.
Caused by: com.itextpdf.text.pdf.PdfXConformanceException: All the fonts must be embedded. This one isn't: Helvetica
at com.itextpdf.text.pdf.internal.PdfXConformanceImp.checkPDFXConformance(PdfXConformanceImp.java:225)
at com.itextpdf.text.pdf.PdfWriter.addSimple(PdfWriter.java:2192)
at com.itextpdf.text.pdf.PdfContentByte.setFontAndSize(PdfContentByte.java:1444)
at com.itextpdf.text.pdf.PdfDocument.writeLineToContent(PdfDocument.java:1463)
at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:968)
at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:841)
at com.itextpdf.text.pdf.ColumnText.showTextAligned(ColumnText.java:1189)
at com.itextpdf.text.pdf.ColumnText.showTextAligned(ColumnText.java:1208)
at com.itextpdf.text.pdf.PdfDocument.flushLines(PdfDocument.java:1193)
at com.itextpdf.text.pdf.PdfDocument.newPage(PdfDocument.java:830)
at com.itextpdf.text.Document.newPage(Document.java:367)
У меня кончились идеи, как избавиться от Helvetica на данный момент ... пытаясь решить эту проблему в течение 8 с лишним часов ... еще идеи?