使用Itext找出PDf中未嵌入Font的位置或页面

时间:2016-03-02 07:23:13

标签: java pdf itext pdf-parsing

我正在使用Itext库来操纵我的PDF。

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

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

1 个答案:

答案 0 :(得分:3)

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

如果需要确定完全使用哪种字体,则必须使用不同的机制,解析器包类具有自定义渲染侦听器。然后,此侦听器可以在使用此类非嵌入字体时执行文本绘制操作。

解析器框架

要找出页面上实际使用某些资源的位置,您必须解析页面内容流并检查其中的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
        ...
    }
}