使用 Itext 找出字体未嵌入 PDf 的位置或页面

Find out the location or page where the Font was not embedded in PDf using Itext

我正在使用 Itext 库来处理我的 PDF。

我正在使用此示例 http://developers.itextpdf.com/examples/itext-action-second-edition/chapter-16#616-listusedfonts.java 找出未嵌入 PDF 中的字体。

库是否提供任何选项来检查 PDF 中未嵌入字体的确切位置?

sample referenced by the OP 仅检查页面和从中引用的 xobject 表单,并输出有关这些实体资源中提供的字体的信息。

如果需要精确定位确切地使用了哪种字体,则必须使用不同的机制,解析器包类带有自定义渲染监听器.然后,此侦听器可以在使用此类未嵌入字体时对文本绘制操作进行操作。

解析器框架

要找出页面上实际使用某些资源的位置,您必须解析页面内容流并检查其中的 PDF 说明。

iText 通过提供一个读取内容流并对其进行预分析的解析器框架来帮助您这样做。第一次分析的结果将转发给您提供的渲染侦听器。

你这样使用解析器框架:

PdfReader reader = new PdfReader(SOURCE);
for (int page = from; page <= to; page++)
{
    PdfReaderContentParser parser = new PdfReaderContentParser(reader);
    RenderListener renderListener = YOUR_RENDER_LISTENER_IMPLEMENTATION;
    parser.processContent(page, renderListener);
    // after the page has been processed, probably 
    // some render listener related post-processing
}

例如文本提取,您通常使用渲染侦听器实现 LocationTextExtractionStrategySimpleTextExtractionStrategy(iText 随附),在处理页面后,您从它具有的策略中检索文本的 String从页面的事件中提取。

要自定义的渲染监听器

iText 5 中的渲染监听器必须实现接口 RenderListener:

public interface RenderListener {
    /**
     * Called when a new text block is beginning (i.e. BT)
     */
    public void beginTextBlock();

    /**
     * Called when text should be rendered
     * @param renderInfo information specifying what to render
     */
    public void renderText(TextRenderInfo renderInfo);

    /**
     * Called when a text block has ended (i.e. ET)
     */
    public void endTextBlock();

    /**
     * Called when image should be rendered
     * @param renderInfo information specifying what to render
     */
    public void renderImage(ImageRenderInfo renderInfo);
}

ExtRenderListener 声明了一些额外的侦听器方法。

您的任务的渲染侦听器,即用于查找给定字体用于绘制文本的确切位置的渲染侦听器,只需要非平凡地实现 renderText,例如像这样:

public void renderText(TextRenderInfo renderInfo)
{
    DocumentFont documentFont = renderInfo.getFont();
    PdfDictionary font = documentFont.getFontDictionary();
    // Check the font dictionary like in your example code
    if (font FULFILLS SOME CRITERIA)
    {
        // The text
        String text = renderInfo.getText();
        // is rendered on the current page on the base line
        LineSegment baseline = renderInfo.getBaseline();
        // using a font fulfilling the given criteria
        ...
    }
}