2011-01-10 5 views
2

Wie überprüft man, ob alle in einer PDF-Datei verwendeten Schriften mit Java und iText in die Datei eingebettet sind? Ich habe einige vorhandene PDF-Dokumente, und ich möchte bestätigen, dass sie nur eingebettete Schriftarten verwenden.Wie überprüft man, ob alle verwendeten Schriften mit Java iText in PDF eingebettet sind?

Dazu muss überprüft werden, dass keine PDF-Standardschriftarten verwendet werden und andere verwendete Schriftarten in die Datei eingebettet sind.

Antwort

2

Sehen Sie sich das ListUsedFonts-Beispiel von iText in Action an.

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

sieht wie folgt aus den in einem pdf verwendeten Schriftarten gedruckt werden, und wenn sie eingebettet sind.

/* 
* 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(); 
    } 
} 
+0

Aus irgendeinem Grund, dass Snippet diese Schriftart nicht finden: eingebettete Typ 1 CFF (CID) Schriftart AllAndNone –

+0

Das Snippet ist in einem Fall falsch: FontDescriptor und FontFile-Knoten einer Schriftart können definiert werden auch in Font 'DescendantFont-Knoten. –

+0

@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. –

0

Wenn Sie Chunk erstellen, deklarieren Sie, welche Schriftart Sie verwenden.
Erstellen Sie BaseFont aus der Schriftart, die Sie verwenden möchten, und deklarieren Sie als BaseFont.EMBEDDED.
Hinweis: Wenn Sie die Option Teilmenge nicht auf true setzen, wird die gesamte Schriftart eingebettet.

Beachten Sie, dass die eingebettete Schriftart möglicherweise Urheberrechte verletzt.

+0

Ich bin nicht ein PDF-Dokument erstellen, Ich habe bereits eine PDF, die ich überprüfen möchte –

-1

Ich glaube nicht, dass dies ein "iText" Anwendungsfall ist. Verwenden Sie entweder PDFBox oder jPod. Diese implementieren das PDF-Modell und als solche können Sie:

  • öffnen Sie das Dokument
  • recurse aus dem Dokument Wurzel nach unten Objektbaum
  • überprüfen, ob dies ein Objekt Schriftart ist
  • prüft, ob die Schriftart Datei verfügbar

geprüft, ob nur eingebettete Schriften sind verwendet weitaus komplexer ist (dies ist, Schriften, die nicht eingebettet sind, aber nicht verwendet werden, sind in Ordnung).

1
/** 
* 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.

-1

Die einfachste Antwort ist die PDF-Datei mit Adobe Acrobat dann zu öffnen:

  1. , klicken Sie auf Datei
  2. wählen Sie Eigenschaften
  3. Klick auf die Registerkarte Schriftarten

Diese zeigen Sie eine Liste aller Schriftarten im Dokument. Jede eingebettete Schriftart zeigt neben dem Namen der Schriftart "(Embedded)" an.

Zum Beispiel:

ACaslonPro-Bold (Embedded)

wo ACaslonPro-Bold wird aus dem Dateinamen abgeleitet, dass Sie es mit einem integrierten (zB FontFactory.register("/path/to/ACaslonPro-Bold.otf",...

Verwandte Themen