如何使用Java iText检查所有使用的字体是否嵌入到PDF中?

时间:2011-01-10 11:05:01

标签: java pdf fonts itext

如何检查PDF文件中使用的所有字体是否都嵌入到带有Java和iText的文件中?我有一些现有的PDF文档,我想验证他们只使用 嵌入字体。

这需要检查没有使用PDF标准字体,并且文件中嵌入了其他使用的字体。

4 个答案:

答案 0 :(得分:3)

查看行动中iText的ListUsedFonts示例。

http://itextpdf.com/examples/iia.php?id=287

看起来这会打印出pdf中使用的字体以及它们是否嵌入。

/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */

package part4.chapter16;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Set;
import java.util.TreeSet;

import part3.chapter11.FontTypes;

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfReader;

public class ListUsedFonts {

    /** The resulting PDF file. */
    public static String RESULT
        = "results/part4/chapter16/fonts.txt";

    /**
     * Creates a Set containing information about the fonts in the src PDF file.
     * @param src the path to a PDF file
     * @throws IOException
     */
    public Set<String> listFonts(String src) throws IOException {
        Set<String> set = new TreeSet<String>();
        PdfReader reader = new PdfReader(src);
        PdfDictionary resources;
        for (int k = 1; k <= reader.getNumberOfPages(); ++k) {
            resources = reader.getPageN(k).getAsDict(PdfName.RESOURCES);
            processResource(set, resources);
        }
        reader.close();
        return set;
    }

    /**
     * Extracts the font names from page or XObject resources.
     * @param set the set with the font names
     * @param resources the resources dictionary
     */
    public static void processResource(Set<String> set, PdfDictionary resource) {
        if (resource == null)
            return;
        PdfDictionary xobjects = resource.getAsDict(PdfName.XOBJECT);
        if (xobjects != null) {
            for (PdfName key : xobjects.getKeys()) {
                processResource(set, xobjects.getAsDict(key));
            }
        }
        PdfDictionary fonts = resource.getAsDict(PdfName.FONT);
        if (fonts == null)
            return;
        PdfDictionary font;
        for (PdfName key : fonts.getKeys()) {
            font = fonts.getAsDict(key);
            String name = font.getAsName(PdfName.BASEFONT).toString();
            if (name.length() > 8 && name.charAt(7) == '+') {
                name = String.format("%s subset (%s)", name.substring(8), name.substring(1, 7));
            }
            else {
                name = name.substring(1);
                PdfDictionary desc = font.getAsDict(PdfName.FONTDESCRIPTOR);
                if (desc == null)
                    name += " nofontdescriptor";
                else if (desc.get(PdfName.FONTFILE) != null)
                    name += " (Type 1) embedded";
                else if (desc.get(PdfName.FONTFILE2) != null)
                    name += " (TrueType) embedded";
                else if (desc.get(PdfName.FONTFILE3) != null)
                    name += " (" + font.getAsName(PdfName.SUBTYPE).toString().substring(1) + ") embedded";
            }
            set.add(name);
        }
    }

    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        new FontTypes().createPdf(FontTypes.RESULT);
        Set<String> set = new ListUsedFonts().listFonts(FontTypes.RESULT);
        PrintWriter out = new PrintWriter(new FileOutputStream(RESULT));
        for (String fontname : set)
            out.println(fontname);
        out.flush();
        out.close();
    }
}

答案 1 :(得分:0)

创建Chunk时,声明您使用的字体。
从您要使用的字体创建BaseFont并声明为BaseFont.EMBEDDED 请注意,如果未将选项 subset 设置为true,则将嵌入整个字体。

请注意,嵌入字体可能会侵犯作者权利。

答案 2 :(得分:-1)

我不认为这是一个“iText”用例。使用PDFBoxjPod。这些实现了PDF模型,因此您可以:

  • 打开文档
  • 从文档根据对象树递归
  • 检查这是否是字体对象
  • 检查字体文件是否可用

检查嵌入字体是否仅使用要复杂得多(这是非嵌入但未使用的字体很好)。

答案 3 :(得分:-1)

最简单的答案是用Adobe Acrobat打开PDF文件:

  1. 点击文件
  2. 选择属性
  3. 点击“字体”标签
  4. 这将显示文档中所有字体的列表。嵌入的任何字体都会在字体名称旁边显示“(嵌入)”。

    例如:

    ACaslonPro-Bold(嵌入式)

    其中ACaslonPro-Bold源自您嵌入的文件名(例如FontFactory.register("/path/to/ACaslonPro-Bold.otf",...