/**
* Creates a set containing information about the not-embedded fonts within 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;
}
/**
* Finds out if the font is an embedded subset font
* @param font name
* @return true if the name denotes an embedded subset font
*/
private boolean isEmbeddedSubset(String name) {
//name = String.format("%s subset (%s)", name.substring(8), name.substring(1, 7));
return name != null && name.length() > 8 && name.charAt(7) == '+';
}
private void processFont(PdfDictionary font, Set<String> set) {
String name = font.getAsName(PdfName.BASEFONT).toString();
if(isEmbeddedSubset(name))
return;
PdfDictionary desc = font.getAsDict(PdfName.FONTDESCRIPTOR);
//nofontdescriptor
if (desc == null) {
PdfArray descendant = font.getAsArray(PdfName.DESCENDANTFONTS);
if (descendant == null) {
set.add(name.substring(1));
}
else {
for (int i = 0; i < descendant.size(); i++) {
PdfDictionary dic = descendant.getAsDict(i);
processFont(dic, set);
}
}
}
/**
* (Type 1) embedded
*/
else if (desc.get(PdfName.FONTFILE) != null)
;
/**
* (TrueType) embedded
*/
else if (desc.get(PdfName.FONTFILE2) != null)
;
/**
* " (" + font.getAsName(PdfName.SUBTYPE).toString().substring(1) + ") embedded"
*/
else if (desc.get(PdfName.FONTFILE3) != null)
;
else {
set.add(name.substring(1));
}
}
/**
* Extracts the names of the not-embedded fonts from page or XObject resources.
* @param set the set with the font names
* @param resources the resources dictionary
*/
public 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);
processFont(font, set);
}
}
Der obige Code verwendet werden könnten, die Schriften abzurufen, die in der angegebenen PDF-Datei eingebettet sind, nicht. Ich habe den Code von iText in Action verbessert, so dass er auch DescendantFont von Font verarbeiten kann.
Aus irgendeinem Grund, dass Snippet diese Schriftart nicht finden: eingebettete Typ 1 CFF (CID) Schriftart AllAndNone –
Das Snippet ist in einem Fall falsch: FontDescriptor und FontFile-Knoten einer Schriftart können definiert werden auch in Font 'DescendantFont-Knoten. –
@Mark, wenn die Verknüpfung zum Code nicht mehr angezeigt wird, ist diese Antwort nicht mehr sinnvoll. Bitte überlege, die Antwort mit Code zu aktualisieren. –