]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
More work on PDF/A-1:
authorJeremias Maerki <jeremias@apache.org>
Wed, 22 Feb 2006 15:40:44 +0000 (15:40 +0000)
committerJeremias Maerki <jeremias@apache.org>
Wed, 22 Feb 2006 15:40:44 +0000 (15:40 +0000)
ID entry is now generated in the trailer.
More conformance checks especially for fonts.
PDF/A Identification Schema for XMP added.
Almost finished. Only color space checking is left to do, I think.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@379798 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/fo/extensions/xmp/XMPConstants.java
src/java/org/apache/fop/pdf/PDFCIDFont.java
src/java/org/apache/fop/pdf/PDFDocument.java
src/java/org/apache/fop/pdf/PDFFont.java
src/java/org/apache/fop/pdf/PDFFontDescriptor.java
src/java/org/apache/fop/pdf/PDFFontNonBase14.java
src/java/org/apache/fop/pdf/PDFMetadata.java
src/java/org/apache/fop/pdf/PDFXObject.java

index ed189aa3837dc2891d981aad1997840f07a8bfb7..6edb1fa41c18d2ab54e66e3d0c16a6f1cb49e7f2 100644 (file)
@@ -37,5 +37,8 @@ public interface XMPConstants {
     
     /** Namespace URI for the Adobe PDF Schema */
     String ADOBE_PDF_NAMESPACE = "http://ns.adobe.com/pdf/1.3/";
+
+    /** Namespace URI for the PDF/A Identification Schema */
+    String PDF_A_IDENTIFICATION = "http://www.aiim.org/pdfa/ns/id";
     
 }
index ef6188bc574b97744c1d6531494dcd7dd19fe475..7aa3a0ae24fa7574ae62fdc9a6f6340e63d93508 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2004,2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -202,9 +202,12 @@ public class PDFCIDFont extends PDFObject {
         p.append("<< /Type /Font");
         p.append("\n/BaseFont /");
         p.append(this.basefont);
+        p.append(" \n/CIDToGIDMap ");
         if (cidMap != null) {
-            p.append(" \n/CIDToGIDMap ");
             p.append(cidMap.referencePDF());
+        } else {
+            p.append("/Identity");
+            //This is the default. We still write it because PDF/A requires it.
         }
         p.append(" \n/Subtype /");
         p.append(getPDFNameForCIDFontType(this.cidtype));
index 779e7ff26fce92c6922d6940fe8e6de1d6a28f6c..79b7e52e1352a814f97d8aefac1732fd41329027 100644 (file)
@@ -23,6 +23,10 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -882,6 +886,27 @@ public class PDFDocument {
         this.position += bin.length;
     }
 
+    /** @return the "ID" entry for the file trailer */
+    protected String getIDEntry() {
+        try {
+            MessageDigest digest = MessageDigest.getInstance("MD5");
+            DateFormat df = new SimpleDateFormat("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS");
+            digest.update(df.format(new Date()).getBytes());
+            //Ignoring the filename here for simplicity even though it's recommended by the PDF spec
+            digest.update(String.valueOf(this.position).getBytes());
+            digest.update(getInfo().toPDF());
+            byte[] res = digest.digest();
+            String s = PDFText.toHex(res);
+            return "/ID [" + s + " " + s + "]";
+        } catch (NoSuchAlgorithmException e) {
+            if (getPDFAMode().isPDFA1LevelB()) {
+                throw new UnsupportedOperationException("MD5 not available: " + e.getMessage());
+            } else {
+                return ""; //Entry is optional if PDF/A is not active
+            }
+        }
+    }
+    
     /**
      * write the trailer
      *
@@ -920,6 +945,8 @@ public class PDFDocument {
                 + "/Info "
                 + this.info.referencePDF()
                 + "\n"
+                + getIDEntry()
+                + "\n"
                 + encryptEntry
                 + ">>\n"
                 + "startxref\n"
index fd0f51a7360e4e87dc64949f6668392e7b3587e7..9b827ebf1a53c0e4b17d9a4259a5799cd66f7fb6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2004,2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -189,10 +189,23 @@ public class PDFFont extends PDFObject {
         }
     }
 
+    /**
+     * Validates the PDF object prior to serialization.
+     */
+    protected void validate() {
+        if (getDocumentSafely().getPDFAMode().isPDFA1LevelB()) {
+            if (this.getClass() == PDFFont.class) {
+                throw new PDFConformanceException("For PDF/A-1, all fonts, even the base 14"
+                    + " fonts, have to be embedded!");
+            }
+        }
+    }
+    
     /**
      * @see org.apache.fop.pdf.PDFObject#toPDFString()
      */
     public String toPDFString() {
+        validate();
         StringBuffer p = new StringBuffer(128);
         p.append(getObjectID());
         p.append("<< /Type /Font\n/Subtype /"
index 83492ffcf1217c1c0cb0309617f0d7f39d9a5dcf..24e0243f5d38a29c610e9cbac0b7bab43bad9888 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2004,2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -114,6 +114,11 @@ public class PDFFontDescriptor extends PDFObject {
         this.fontfile = fontfile;
     }
 
+    /** @return the FontFile or null if the font is not embedded */
+    public AbstractPDFStream getFontFile() {
+        return this.fontfile;
+    }
+    
     // public void setCharSet(){}//for subset fonts
 
     /**
index b18aa66f837f617ade8d30e2646981dac3b52a3f..e32b11ce4d4516843ac2acd4611d6cf3c7bd4b42 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2004,2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -88,6 +88,20 @@ public abstract class PDFFontNonBase14 extends PDFFont {
         this.descriptor = descriptor;
     }
 
+    /** @return the FontDescriptor or null if there is none */
+    public PDFFontDescriptor getDescriptor() {
+        return this.descriptor;
+    }
+    
+    /** @see org.apache.fop.pdf.PDFFont#validate() */
+    protected void validate() {
+        if (getDocumentSafely().getPDFAMode().isPDFA1LevelB()) {
+            if (this.getDescriptor().getFontFile() == null) {
+                throw new PDFConformanceException("For PDF/A-1, all fonts have to be embedded!");
+            }
+        }
+    }
+    
     /**
      * @see org.apache.fop.pdf.PDFFont#fillInPDF(StringBuffer)
      */
index 9b21420eb6343bc4aa693f5a744cd4e307cb5355..6aec41ca532d509b33bf1551a9010a0a37cb32a9 100644 (file)
@@ -230,6 +230,25 @@ public class PDFMetadata extends PDFStream {
         desc.appendChild(el);
         el.appendChild(doc.createTextNode(pdfDoc.getPDFVersionString()));
         
+        //PDF/A identification
+        PDFAMode pdfaMode = pdfDoc.getPDFAMode(); 
+        if (pdfaMode.isPDFA1LevelB()) {
+            desc = doc.createElementNS(XMPConstants.RDF_NAMESPACE, "rdf:Description");
+            desc.setAttribute("about", "");
+            desc.setAttributeNS(xmlns, "xmlns:pdfaid", XMPConstants.PDF_A_IDENTIFICATION);
+            rdf.appendChild(desc);
+            el = doc.createElementNS(XMPConstants.PDF_A_IDENTIFICATION, "pdfaid:part");
+            desc.appendChild(el);
+            el.appendChild(doc.createTextNode("1")); //PDF/A-1
+            el = doc.createElementNS(XMPConstants.PDF_A_IDENTIFICATION, "pdfaid:conformance");
+            desc.appendChild(el);
+            if (pdfaMode == PDFAMode.PDFA_1A) {
+                el.appendChild(doc.createTextNode("A")); //PDF/A-1a
+            } else {
+                el.appendChild(doc.createTextNode("B")); //PDF/A-1b
+            }
+        }
+        
         return doc;
     }
     
index 4d6e7f3802c122e1b626c31f48afd897527780fb..0607add55a0cf723545f1407d7968549dbda2d25 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -94,6 +94,10 @@ public class PDFXObject extends AbstractPDFStream {
     
     private String buildDictionaryFromPS(String lengthEntry, 
                                          String dictEntries) {
+        if (getDocumentSafely().getPDFAMode().isPDFA1LevelB()) {
+            throw new PDFConformanceException("PostScript XObjects are prohibited when PDF/A"
+                    + " is active. Convert EPS graphics to another format.");
+        }
         StringBuffer sb = new StringBuffer(128);
         sb.append(getObjectID());
         sb.append("<</Type /XObject\n");