You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by sp...@apache.org on 2011/09/29 11:49:27 UTC

svn commit: r1177244 [2/3] - in /xmlgraphics/fop/branches/Temp_ComplexScripts: ./ src/documentation/ src/documentation/content/ src/documentation/content/xdocs/ src/documentation/content/xdocs/trunk/ src/java/org/apache/fop/accessibility/ src/java/org/...

Modified: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java?rev=1177244&r1=1177243&r2=1177244&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java (original)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java Thu Sep 29 09:49:24 2011
@@ -21,8 +21,8 @@ package org.apache.fop.fonts.truetype;
 
 import java.io.IOException;
 import java.util.Iterator;
-import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 
 /**
@@ -466,175 +466,6 @@ public class TTFSubSetFile extends TTFFi
     }
 
     /**
-     * Returns a List containing the glyph itself plus all glyphs
-     * that this composite glyph uses
-     */
-    private List getIncludedGlyphs(FontFileReader in, int glyphOffset,
-                                     Integer glyphIdx) throws IOException {
-        List ret = new java.util.ArrayList();
-        ret.add(glyphIdx);
-        int offset = glyphOffset + (int)mtxTab[glyphIdx.intValue()].getOffset() + 10;
-        Integer compositeIdx = null;
-        int flags = 0;
-        boolean moreComposites = true;
-        while (moreComposites) {
-            flags = in.readTTFUShort(offset);
-            compositeIdx = new Integer(in.readTTFUShort(offset + 2));
-            ret.add(compositeIdx);
-
-            offset += 4;
-            if ((flags & 1) > 0) {
-                // ARG_1_AND_ARG_2_ARE_WORDS
-                offset += 4;
-            } else {
-                offset += 2;
-            }
-
-            if ((flags & 8) > 0) {
-                offset += 2;    // WE_HAVE_A_SCALE
-            } else if ((flags & 64) > 0) {
-                offset += 4;    // WE_HAVE_AN_X_AND_Y_SCALE
-            } else if ((flags & 128) > 0) {
-                offset += 8;    // WE_HAVE_A_TWO_BY_TWO
-            }
-
-            if ((flags & 32) > 0) {
-                moreComposites = true;
-            } else {
-                moreComposites = false;
-            }
-        }
-
-        return ret;
-    }
-
-
-    /**
-     * Rewrite all compositepointers in glyphindex glyphIdx
-     *
-     */
-    private void remapComposite(FontFileReader in, Map glyphs,
-                                int glyphOffset,
-                                Integer glyphIdx) throws IOException {
-        int offset = glyphOffset + (int)mtxTab[glyphIdx.intValue()].getOffset()
-                     + 10;
-
-        Integer compositeIdx = null;
-        int flags = 0;
-        boolean moreComposites = true;
-
-        while (moreComposites) {
-            flags = in.readTTFUShort(offset);
-            compositeIdx = new Integer(in.readTTFUShort(offset + 2));
-            Integer newIdx = (Integer)glyphs.get(compositeIdx);
-            if (newIdx == null) {
-                // This errormessage would look much better
-                // if the fontname was printed to
-                //log.error("An embedded font "
-                //                     + "contains bad glyph data. "
-                //                     + "Characters might not display "
-                //                     + "correctly.");
-                moreComposites = false;
-                continue;
-            }
-
-            in.writeTTFUShort(offset + 2, newIdx.intValue());
-
-            offset += 4;
-
-            if ((flags & 1) > 0) {
-                // ARG_1_AND_ARG_2_ARE_WORDS
-                offset += 4;
-            } else {
-                offset += 2;
-            }
-
-            if ((flags & 8) > 0) {
-                offset += 2;    // WE_HAVE_A_SCALE
-            } else if ((flags & 64) > 0) {
-                offset += 4;    // WE_HAVE_AN_X_AND_Y_SCALE
-            } else if ((flags & 128) > 0) {
-                offset += 8;    // WE_HAVE_A_TWO_BY_TWO
-            }
-
-            if ((flags & 32) > 0) {
-                moreComposites = true;
-            } else {
-                moreComposites = false;
-            }
-        }
-    }
-
-
-    /**
-     * Scan all the original glyphs for composite glyphs and add those glyphs
-     * to the glyphmapping also rewrite the composite glyph pointers to the new
-     * mapping
-     */
-    private void scanGlyphs(FontFileReader in,
-                            Map glyphs) throws IOException {
-        TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("glyf");
-        Map newComposites = null;
-        Map allComposites = new java.util.HashMap();
-
-        int newIndex = glyphs.size();
-
-        if (entry != null) {
-            while (newComposites == null || newComposites.size() > 0) {
-                // Inefficient to iterate through all glyphs
-                newComposites = new java.util.HashMap();
-
-                Iterator e = glyphs.keySet().iterator();
-                while (e.hasNext()) {
-                    Integer origIndex = (Integer)e.next();
-
-                    if (in.readTTFShort(entry.getOffset()
-                                        + mtxTab[origIndex.intValue()].getOffset()) < 0) {
-                        // origIndex is a composite glyph
-                        allComposites.put(origIndex, glyphs.get(origIndex));
-                        List composites
-                            = getIncludedGlyphs(in, (int)entry.getOffset(),
-                                              origIndex);
-
-                        // Iterate through all composites pointed to
-                        // by this composite and check if they exists
-                        // in the glyphs map, add them if not.
-                        Iterator cps = composites.iterator();
-                        while (cps.hasNext()) {
-                            Integer cIdx = (Integer)cps.next();
-                            if (glyphs.get(cIdx) == null
-                                    && newComposites.get(cIdx) == null) {
-                                newComposites.put(cIdx,
-                                                  new Integer(newIndex));
-                                newIndex++;
-                            }
-                        }
-                    }
-                }
-
-                // Add composites to glyphs
-                Iterator m = newComposites.keySet().iterator();
-                while (m.hasNext()) {
-                    Integer im = (Integer)m.next();
-                    glyphs.put(im, newComposites.get(im));
-                }
-            }
-
-            // Iterate through all composites to remap their composite index
-            Iterator ce = allComposites.keySet().iterator();
-            while (ce.hasNext()) {
-                remapComposite(in, glyphs, (int)entry.getOffset(),
-                               (Integer)ce.next());
-            }
-
-        } else {
-            throw new IOException("Can't find glyf table");
-        }
-    }
-
-
-
-    /**
      * Returns a subset of the original font.
      *
      * @param in FontFileReader to read from
@@ -704,6 +535,17 @@ public class TTFSubSetFile extends TTFFi
         return ret;
     }
 
+    private void scanGlyphs(FontFileReader in, Map<Integer, Integer> subsetGlyphs)
+            throws IOException {
+        TTFDirTabEntry glyfTableInfo = (TTFDirTabEntry) dirTabs.get("glyf");
+        if (glyfTableInfo == null) {
+            throw new IOException("Glyf table could not be found");
+        }
+
+        GlyfTable glyfTable = new GlyfTable(in, mtxTab, glyfTableInfo, subsetGlyphs);
+        glyfTable.populateGlyphsWithComposites();
+    }
+
     /**
      * writes a ISO-8859-1 string at the currentPosition
      * updates currentPosition but not realSize
@@ -795,15 +637,15 @@ public class TTFSubSetFile extends TTFFi
      * Read a unsigned short value at given position
      */
     private int readUShort(int pos) {
-        int ret = (int)output[pos];
+        int ret = output[pos];
         if (ret < 0) {
             ret += 256;
         }
         ret = ret << 8;
-        if ((int)output[pos + 1] < 0) {
-            ret |= (int)output[pos + 1] + 256;
+        if (output[pos + 1] < 0) {
+            ret |= output[pos + 1] + 256;
         } else {
-            ret |= (int)output[pos + 1];
+            ret |= output[pos + 1];
         }
 
         return ret;
@@ -826,7 +668,7 @@ public class TTFSubSetFile extends TTFFi
      */
     private int maxPow2(int max) {
         int i = 0;
-        while (Math.pow(2, (double)i) < max) {
+        while (Math.pow(2, i) < max) {
             i++;
         }
 
@@ -834,7 +676,7 @@ public class TTFSubSetFile extends TTFFi
     }
 
     private int log2(int num) {
-        return (int)(Math.log((double)num) / Math.log(2));
+        return (int)(Math.log(num) / Math.log(2));
     }
 
 
@@ -853,10 +695,10 @@ public class TTFSubSetFile extends TTFFi
         long sum = 0;
 
         for (int i = 0; i < size; i += 4) {
-            int l = (int)(output[start + i] << 24);
-            l += (int)(output[start + i + 1] << 16);
-            l += (int)(output[start + i + 2] << 16);
-            l += (int)(output[start + i + 3] << 16);
+            int l = (output[start + i] << 24);
+            l += (output[start + i + 1] << 16);
+            l += (output[start + i + 2] << 16);
+            l += (output[start + i + 3] << 16);
             sum += l;
             if (sum > 0xffffffff) {
                 sum = sum - 0xffffffff;

Modified: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFDocument.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFDocument.java?rev=1177244&r1=1177243&r2=1177244&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFDocument.java (original)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFDocument.java Thu Sep 29 09:49:24 2011
@@ -25,10 +25,7 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
 import java.io.Writer;
-import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
@@ -186,6 +183,8 @@ public class PDFDocument {
 
     private boolean encodingOnTheFly = true;
 
+    private FileIDGenerator fileIDGenerator;
+
     /**
      * Creates an empty PDF document.
      *
@@ -513,10 +512,10 @@ public class PDFDocument {
      */
     public void setEncryption(PDFEncryptionParams params) {
         getProfile().verifyEncryptionAllowed();
-        this.encryption = PDFEncryptionManager.newInstance(++this.objectcount, params);
+        fileIDGenerator = FileIDGenerator.getRandomFileIDGenerator();
+        this.encryption = PDFEncryptionManager.newInstance(++this.objectcount, params, this);
         if (this.encryption != null) {
             PDFObject pdfObject = (PDFObject)this.encryption;
-            pdfObject.setDocument(this);
             addTrailerObject(pdfObject);
         } else {
             log.warn(
@@ -979,27 +978,6 @@ 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(encode(df.format(new Date())));
-            //Ignoring the filename here for simplicity even though it's recommended by the PDF spec
-            digest.update(encode(String.valueOf(this.position)));
-            digest.update(getInfo().toPDF());
-            byte[] res = digest.digest();
-            String s = PDFText.toHex(res);
-            return "/ID [" + s + " " + s + "]";
-        } catch (NoSuchAlgorithmException e) {
-            if (getProfile().isIDEntryRequired()) {
-                throw new UnsupportedOperationException("MD5 not available: " + e.getMessage());
-            } else {
-                return ""; //Entry is optional if PDF/A or PDF/X are not active
-            }
-        }
-    }
-
     /**
      * Write the trailer
      *
@@ -1038,7 +1016,9 @@ public class PDFDocument {
         if (this.isEncryptionActive()) {
             pdf.append(this.encryption.getTrailerEntry());
         } else {
-            pdf.append(this.getIDEntry());
+            byte[] fileID = getFileIDGenerator().getOriginalFileID();
+            String fileIDAsString = PDFText.toHex(fileID);
+            pdf.append("/ID [" + fileIDAsString + " " + fileIDAsString + "]");
         }
 
         pdf.append("\n>>\nstartxref\n")
@@ -1089,4 +1069,18 @@ public class PDFDocument {
         return pdfBytes.length;
     }
 
+    long getCurrentFileSize() {
+        return position;
+    }
+
+    FileIDGenerator getFileIDGenerator() {
+        if (fileIDGenerator == null) {
+            try {
+                fileIDGenerator = FileIDGenerator.getDigestFileIDGenerator(this);
+            } catch (NoSuchAlgorithmException e) {
+                fileIDGenerator = FileIDGenerator.getRandomFileIDGenerator();
+            }
+        }
+        return fileIDGenerator;
+    }
 }

Modified: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFEncryption.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFEncryption.java?rev=1177244&r1=1177243&r2=1177244&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFEncryption.java (original)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFEncryption.java Thu Sep 29 09:49:24 2011
@@ -25,18 +25,6 @@ package org.apache.fop.pdf;
 public interface PDFEncryption {
 
     /**
-     * Returns the encryption parameters.
-     * @return the encryption parameters
-     */
-    PDFEncryptionParams getParams();
-
-    /**
-     * Sets the encryption parameters.
-     * @param params The parameterss to set
-     */
-    void setParams(PDFEncryptionParams params);
-
-    /**
      * Adds a PDFFilter to the PDFStream object
      * @param stream the stream to add an encryption filter to
      */

Modified: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFEncryptionJCE.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFEncryptionJCE.java?rev=1177244&r1=1177243&r2=1177244&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFEncryptionJCE.java (original)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFEncryptionJCE.java Thu Sep 29 09:49:24 2011
@@ -19,13 +19,12 @@
 
 package org.apache.fop.pdf;
 
-// Java
 import java.io.IOException;
 import java.io.OutputStream;
 import java.security.InvalidKeyException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
-import java.util.Random;
+import java.util.Arrays;
 
 import javax.crypto.BadPaddingException;
 import javax.crypto.Cipher;
@@ -35,310 +34,427 @@ import javax.crypto.NoSuchPaddingExcepti
 import javax.crypto.spec.SecretKeySpec;
 
 /**
- * class representing a /Filter /Standard object.
- *
+ * An implementation of the Standard Security Handler.
  */
-public class PDFEncryptionJCE extends PDFObject implements PDFEncryption {
+public final class PDFEncryptionJCE extends PDFObject implements PDFEncryption {
 
-    private class EncryptionFilter extends PDFFilter {
-        private PDFEncryptionJCE encryption;
-        private int number;
-        private int generation;
+    private final MessageDigest digest;
 
-        /**
-         * The constructor for the internal PDFEncryptionJCE filter
-         * @param encryption The encryption object to use
-         * @param number The number of the object to be encrypted
-         * @param generation The generation of the object to be encrypted
-         */
-        public EncryptionFilter(PDFEncryptionJCE encryption,
-                                int number, int generation) {
-            super();
-            this.encryption = encryption;
-            this.number  = number;
-            this.generation = generation;
-            log.debug("new encryption filter for number "
-                + number + " and generation " + generation);
+    private byte[] encryptionKey;
+
+    private String encryptionDictionary;
+
+    private class EncryptionInitializer {
+
+        private final PDFEncryptionParams encryptionParams;
+
+        private int encryptionLength;
+
+        private int version;
+
+        private int revision;
+
+        EncryptionInitializer(PDFEncryptionParams params) {
+            this.encryptionParams = new PDFEncryptionParams(params);
+        }
+
+        void init() {
+            encryptionLength = encryptionParams.getEncryptionLengthInBits();
+            determineEncryptionAlgorithm();
+            int permissions = Permission.computePermissions(encryptionParams);
+            EncryptionSettings encryptionSettings = new EncryptionSettings(
+                    encryptionLength, permissions,
+                    encryptionParams.getUserPassword(), encryptionParams.getOwnerPassword());
+            InitializationEngine initializationEngine = (revision == 2)
+                    ? new Rev2Engine(encryptionSettings)
+                    : new Rev3Engine(encryptionSettings);
+            initializationEngine.run();
+            encryptionDictionary = createEncryptionDictionary(getObjectID(), permissions,
+                    initializationEngine.oValue, initializationEngine.uValue);
         }
 
+        private void determineEncryptionAlgorithm() {
+            if (isVersion1Revision2Algorithm()) {
+                version = 1;
+                revision = 2;
+            } else {
+                version = 2;
+                revision = 3;
+            }
+        }
+
+        private boolean isVersion1Revision2Algorithm() {
+            return encryptionLength == 40
+                    && encryptionParams.isAllowFillInForms()
+                    && encryptionParams.isAllowAccessContent()
+                    && encryptionParams.isAllowAssembleDocument()
+                    && encryptionParams.isAllowPrintHq();
+        }
+
+        private String createEncryptionDictionary(final String objectId, final int permissions,
+                final byte[] oValue, final byte[] uValue) {
+            return objectId
+                    + "<< /Filter /Standard\n"
+                    + "/V " + version + "\n"
+                    + "/R " + revision + "\n"
+                    + "/Length " + encryptionLength + "\n"
+                    + "/P "  + permissions + "\n"
+                    + "/O " + PDFText.toHex(oValue) + "\n"
+                    + "/U " + PDFText.toHex(uValue) + "\n"
+                    + ">>\n"
+                    + "endobj\n";
+        }
+
+    }
+
+    private static enum Permission {
+
+        PRINT(3),
+        EDIT_CONTENT(4),
+        COPY_CONTENT(5),
+        EDIT_ANNOTATIONS(6),
+        FILL_IN_FORMS(9),
+        ACCESS_CONTENT(10),
+        ASSEMBLE_DOCUMENT(11),
+        PRINT_HQ(12);
+
+        private final int mask;
+
         /**
-         * Return a PDF string representation of the filter. In this
-         * case no filter name is passed.
-         * @return The filter name, blank in this case
+         * Creates a new permission.
+         *
+         * @param bit bit position for this permission, 1-based to match the PDF Reference
          */
-        public String getName() {
-            return "";
+        private Permission(int bit) {
+            mask = 1 << (bit - 1);
+        }
+
+        private int removeFrom(int permissions) {
+            return permissions - mask;
+        }
+
+        static int computePermissions(PDFEncryptionParams encryptionParams) {
+            int permissions = -4;
+
+            if (!encryptionParams.isAllowPrint()) {
+                permissions = PRINT.removeFrom(permissions);
+            }
+            if (!encryptionParams.isAllowCopyContent()) {
+                permissions = COPY_CONTENT.removeFrom(permissions);
+            }
+            if (!encryptionParams.isAllowEditContent()) {
+                permissions = EDIT_CONTENT.removeFrom(permissions);
+            }
+            if (!encryptionParams.isAllowEditAnnotations()) {
+                permissions = EDIT_ANNOTATIONS.removeFrom(permissions);
+            }
+            if (!encryptionParams.isAllowFillInForms()) {
+                permissions = FILL_IN_FORMS.removeFrom(permissions);
+            }
+            if (!encryptionParams.isAllowAccessContent()) {
+                permissions = ACCESS_CONTENT.removeFrom(permissions);
+            }
+            if (!encryptionParams.isAllowAssembleDocument()) {
+                permissions = ASSEMBLE_DOCUMENT.removeFrom(permissions);
+            }
+            if (!encryptionParams.isAllowPrintHq()) {
+                permissions = PRINT_HQ.removeFrom(permissions);
+            }
+            return permissions;
+        }
+    }
+
+    private static final class EncryptionSettings {
+
+        final int encryptionLength; // CSOK: VisibilityModifier
+
+        final int permissions; // CSOK: VisibilityModifier
+
+        final String userPassword; // CSOK: VisibilityModifier
+
+        final String ownerPassword; // CSOK: VisibilityModifier
+
+        EncryptionSettings(int encryptionLength, int permissions,
+                String userPassword, String ownerPassword) {
+            this.encryptionLength = encryptionLength;
+            this.permissions = permissions;
+            this.userPassword = userPassword;
+            this.ownerPassword = ownerPassword;
+        }
+
+    }
+
+    private abstract class InitializationEngine {
+
+        /** Padding for passwords. */
+        protected final byte[] padding = new byte[] {
+                (byte) 0x28, (byte) 0xBF, (byte) 0x4E, (byte) 0x5E,
+                (byte) 0x4E, (byte) 0x75, (byte) 0x8A, (byte) 0x41,
+                (byte) 0x64, (byte) 0x00, (byte) 0x4E, (byte) 0x56,
+                (byte) 0xFF, (byte) 0xFA, (byte) 0x01, (byte) 0x08,
+                (byte) 0x2E, (byte) 0x2E, (byte) 0x00, (byte) 0xB6,
+                (byte) 0xD0, (byte) 0x68, (byte) 0x3E, (byte) 0x80,
+                (byte) 0x2F, (byte) 0x0C, (byte) 0xA9, (byte) 0xFE,
+                (byte) 0x64, (byte) 0x53, (byte) 0x69, (byte) 0x7A};
+
+        protected final int encryptionLengthInBytes;
+
+        private final int permissions;
+
+        private byte[] oValue;
+
+        private byte[] uValue;
+
+        private final byte[] preparedUserPassword;
+
+        protected final String ownerPassword;
+
+        InitializationEngine(EncryptionSettings encryptionSettings) {
+            this.encryptionLengthInBytes = encryptionSettings.encryptionLength / 8;
+            this.permissions = encryptionSettings.permissions;
+            this.preparedUserPassword = preparePassword(encryptionSettings.userPassword);
+            this.ownerPassword = encryptionSettings.ownerPassword;
+        }
+
+        void run() {
+            oValue = computeOValue();
+            createEncryptionKey();
+            uValue = computeUValue();
         }
 
         /**
-         * Return a parameter dictionary for this filter, or null
-         * @return The parameter dictionary. In this case, null.
+         * Applies Algorithm 3.3 Page 79 of the PDF 1.4 Reference.
+         *
+         * @return the O value
          */
-        public PDFObject getDecodeParms() {
-            return null;
+        private byte[] computeOValue() {
+            // Step 1
+            byte[] md5Input = prepareMD5Input();
+            // Step 2
+            digest.reset();
+            byte[] hash = digest.digest(md5Input);
+            // Step 3
+            hash = computeOValueStep3(hash);
+            // Step 4
+            byte[] key = new byte[encryptionLengthInBytes];
+            System.arraycopy(hash, 0, key, 0, encryptionLengthInBytes);
+            // Steps 5, 6
+            byte[] encryptionResult = encryptWithKey(key, preparedUserPassword);
+            // Step 7
+            encryptionResult = computeOValueStep7(key, encryptionResult);
+            // Step 8
+            return encryptionResult;
         }
 
         /**
-         * {@inheritDoc}
+         * Applies Algorithm 3.2 Page 78 of the PDF 1.4 Reference.
          */
-        public OutputStream applyFilter(OutputStream out) throws IOException {
-            return new CipherOutputStream(out,
-                    encryption.initCipher(number, generation));
+        private void createEncryptionKey() {
+            // Steps 1, 2
+            digest.reset();
+            digest.update(preparedUserPassword);
+            // Step 3
+            digest.update(oValue);
+            // Step 4
+            digest.update((byte) (permissions >>> 0));
+            digest.update((byte) (permissions >>> 8));
+            digest.update((byte) (permissions >>> 16));
+            digest.update((byte) (permissions >>> 24));
+            // Step 5
+            digest.update(getDocumentSafely().getFileIDGenerator().getOriginalFileID());
+            byte[] hash = digest.digest();
+            // Step 6
+            hash = createEncryptionKeyStep6(hash);
+            // Step 7
+            encryptionKey = new byte[encryptionLengthInBytes];
+            System.arraycopy(hash, 0, encryptionKey, 0, encryptionLengthInBytes);
         }
 
-    }
+        protected abstract byte[] computeUValue();
 
-    private static final char [] PAD
-                             = {0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41,
-                                0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08,
-                                0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80,
-                                0x2F, 0x0C, 0xA9, 0xFE, 0x64, 0x53, 0x69, 0x7A};
-
-    /** Value of PRINT permission */
-    public static final int PERMISSION_PRINT            =  4;
-    /** Value of content editting permission */
-    public static final int PERMISSION_EDIT_CONTENT     =  8;
-    /** Value of content extraction permission */
-    public static final int PERMISSION_COPY_CONTENT     = 16;
-    /** Value of annotation editting permission */
-    public static final int PERMISSION_EDIT_ANNOTATIONS = 32;
-
-    // Encryption tools
-    private MessageDigest digest = null;
-    //private Cipher cipher = null;
-    private Random random = new Random();
-    // Control attributes
-    private PDFEncryptionParams params;
-    // Output attributes
-    private byte[] fileID = null;
-    private byte[] encryptionKey = null;
-    private String dictionary = null;
+        /**
+         * Adds padding to the password as directed in page 78 of the PDF 1.4 Reference.
+         *
+         * @param password the password
+         * @return the password with additional padding if necessary
+         */
+        private byte[] preparePassword(String password) {
+            int finalLength = 32;
+            byte[] preparedPassword = new byte[finalLength];
+            byte[] passwordBytes = password.getBytes();
+            System.arraycopy(passwordBytes, 0, preparedPassword, 0, passwordBytes.length);
+            System.arraycopy(padding, 0, preparedPassword, passwordBytes.length,
+                    finalLength - passwordBytes.length);
+            return preparedPassword;
+        }
 
-    /**
-     * Create a /Filter /Standard object.
-     *
-     * @param objnum the object's number
-     */
-    public PDFEncryptionJCE(int objnum) {
-        /* generic creation of object */
-        super();
-        setObjectNumber(objnum);
-        try {
-            digest = MessageDigest.getInstance("MD5");
-            //cipher = Cipher.getInstance("RC4");
-        } catch (NoSuchAlgorithmException e) {
-            throw new UnsupportedOperationException(e.getMessage());
-        /*} catch (NoSuchPaddingException e) {
-            throw new UnsupportedOperationException(e.getMessage());*/
+        private byte[] prepareMD5Input() {
+            if (ownerPassword.length() != 0) {
+                return preparePassword(ownerPassword);
+            } else {
+                return preparedUserPassword;
+            }
         }
-    }
 
-    /**
-     * Local factory method.
-     * @param objnum PDF object number for the encryption object
-     * @param params PDF encryption parameters
-     * @return PDFEncryption the newly created PDFEncryption object
-     */
-    public static PDFEncryption make(int objnum, PDFEncryptionParams params) {
-        PDFEncryptionJCE impl = new PDFEncryptionJCE(objnum);
-        impl.setParams(params);
-        impl.init();
-        return impl;
-    }
+        protected abstract byte[] computeOValueStep3(byte[] hash);
 
+        protected abstract byte[] computeOValueStep7(byte[] key, byte[] encryptionResult);
 
-    /**
-     * Returns the encryption parameters.
-     * @return the encryption parameters
-     */
-    public PDFEncryptionParams getParams() {
-        return this.params;
-    }
+        protected abstract byte[] createEncryptionKeyStep6(byte[] hash);
 
-    /**
-     * Sets the encryption parameters.
-     * @param params The parameterss to set
-     */
-    public void setParams(PDFEncryptionParams params) {
-        this.params = params;
     }
 
-    // Internal procedures
+    private class Rev2Engine extends InitializationEngine {
 
-    private byte[] prepPassword(String password) {
-        byte[] obuffer = new byte[32];
-        byte[] pbuffer = password.getBytes();
+        Rev2Engine(EncryptionSettings encryptionSettings) {
+            super(encryptionSettings);
+        }
+
+        @Override
+        protected byte[] computeOValueStep3(byte[] hash) {
+            return hash;
+        }
 
-        int i = 0;
-        int j = 0;
+        @Override
+        protected byte[] computeOValueStep7(byte[] key, byte[] encryptionResult) {
+            return encryptionResult;
+        }
 
-        while (i < obuffer.length && i < pbuffer.length) {
-            obuffer[i] = pbuffer[i];
-            i++;
+        @Override
+        protected byte[] createEncryptionKeyStep6(byte[] hash) {
+            return hash;
         }
-        while (i < obuffer.length) {
-            obuffer[i++] = (byte) PAD[j++];
+
+        @Override
+        protected byte[] computeUValue() {
+            return encryptWithKey(encryptionKey, padding);
         }
 
-        return obuffer;
     }
 
-    /**
-     * Returns the document file ID
-     * @return The file ID
-     */
-    public byte[] getFileID() {
-        if (fileID == null) {
-            fileID = new byte[16];
-            random.nextBytes(fileID);
+    private class Rev3Engine extends InitializationEngine {
+
+        Rev3Engine(EncryptionSettings encryptionSettings) {
+            super(encryptionSettings);
         }
 
-        return fileID;
-    }
+        @Override
+        protected byte[] computeOValueStep3(byte[] hash) {
+            for (int i = 0; i < 50; i++) {
+                hash = digest.digest(hash);
+            }
+            return hash;
+        }
 
-    /**
-     * This method returns the indexed file ID
-     * @param index The index to access the file ID
-     * @return The file ID
-     */
-    public String getFileID(int index) {
-        if (index == 1) {
-            return PDFText.toHex(getFileID());
+        @Override
+        protected byte[] computeOValueStep7(byte[] key, byte[] encryptionResult) {
+            return xorKeyAndEncrypt19Times(key, encryptionResult);
         }
 
-        byte[] id = new byte[16];
-        random.nextBytes(id);
-        return PDFText.toHex(id);
-    }
+        @Override
+        protected byte[] createEncryptionKeyStep6(byte[] hash) {
+            for (int i = 0; i < 50; i++) {
+                digest.update(hash, 0, encryptionLengthInBytes);
+                hash = digest.digest();
+            }
+            return hash;
+        }
 
-    private byte[] encryptWithKey(byte[] data, byte[] key) {
-        try {
-            final Cipher c = initCipher(key);
-            return c.doFinal(data);
-        } catch (IllegalBlockSizeException e) {
-            throw new IllegalStateException(e.getMessage());
-        } catch (BadPaddingException e) {
-            throw new IllegalStateException(e.getMessage());
+        @Override
+        protected byte[] computeUValue() {
+            // Step 1 is encryptionKey
+            // Step 2
+            digest.reset();
+            digest.update(padding);
+            // Step 3
+            digest.update(getDocumentSafely().getFileIDGenerator().getOriginalFileID());
+            // Step 4
+            byte[] encryptionResult = encryptWithKey(encryptionKey, digest.digest());
+            // Step 5
+            encryptionResult = xorKeyAndEncrypt19Times(encryptionKey, encryptionResult);
+            // Step 6
+            byte[] uValue = new byte[32];
+            System.arraycopy(encryptionResult, 0, uValue, 0, 16);
+            // Add the arbitrary padding
+            Arrays.fill(uValue, 16, 32, (byte) 0);
+            return uValue;
         }
-    }
 
-    private Cipher initCipher(byte[] key) {
-        try {
-            Cipher c = Cipher.getInstance("RC4");
-            SecretKeySpec keyspec = new SecretKeySpec(key, "RC4");
-            c.init(Cipher.ENCRYPT_MODE, keyspec);
-            return c;
-        } catch (InvalidKeyException e) {
-            throw new IllegalStateException(e.getMessage());
-        } catch (NoSuchAlgorithmException e) {
-            throw new UnsupportedOperationException(e.getMessage());
-        } catch (NoSuchPaddingException e) {
-            throw new UnsupportedOperationException(e.getMessage());
+        private byte[] xorKeyAndEncrypt19Times(byte[] key, byte[] input) {
+            byte[] result = input;
+            byte[] encryptionKey = new byte[key.length];
+            for (int i = 1; i <= 19; i++) {
+                for (int j = 0; j < key.length; j++) {
+                    encryptionKey[j] = (byte) (key[j] ^ i);
+                }
+                result = encryptWithKey(encryptionKey, result);
+            }
+            return result;
         }
-    }
 
-    private Cipher initCipher(int number, int generation) {
-        byte[] hash = calcHash(number, generation);
-        int size = hash.length;
-        hash = digest.digest(hash);
-        byte[] key = calcKey(hash, size);
-        return initCipher(key);
     }
 
-    private byte[] encryptWithHash(byte[] data, byte[] hash, int size) {
-        hash = digest.digest(hash);
+    private class EncryptionFilter extends PDFFilter {
 
-        byte[] key = calcKey(hash, size);
+        private int streamNumber;
 
-        return encryptWithKey(data, key);
-    }
+        private int streamGeneration;
+
+        EncryptionFilter(int streamNumber, int streamGeneration) {
+            this.streamNumber  = streamNumber;
+            this.streamGeneration = streamGeneration;
+        }
+
+        /**
+         * Returns a PDF string representation of this filter.
+         *
+         * @return the empty string
+         */
+        public String getName() {
+            return "";
+        }
 
-    private byte[] calcKey(byte[] hash, int size) {
-        byte[] key = new byte[size];
+        /**
+         * Returns a parameter dictionary for this filter.
+         *
+         * @return null, this filter has no parameters
+         */
+        public PDFObject getDecodeParms() {
+            return null;
+        }
 
-        for (int i = 0; i < size; i++) {
-            key[i] = hash[i];
+        /** {@inheritDoc} */
+        public OutputStream applyFilter(OutputStream out) throws IOException {
+            byte[] key = createEncryptionKey(streamNumber, streamGeneration);
+            Cipher cipher = initCipher(key);
+            return new CipherOutputStream(out, cipher);
         }
-        return key;
+
     }
 
-    /**
-     * This method initializes the encryption algorithms and values
-     */
-    public void init() {
-        // Generate the owner value
-        byte[] oValue;
-        if (params.getOwnerPassword().length() > 0) {
-            oValue = encryptWithHash(
-                    prepPassword(params.getUserPassword()),
-                    prepPassword(params.getOwnerPassword()), 5);
-        } else {
-            oValue = encryptWithHash(
-                    prepPassword(params.getUserPassword()),
-                    prepPassword(params.getUserPassword()), 5);
-        }
-
-        // Generate permissions value
-        int permissions = -4;
-
-        if (!params.isAllowPrint()) {
-            permissions -= PERMISSION_PRINT;
-        }
-        if (!params.isAllowCopyContent()) {
-            permissions -= PERMISSION_COPY_CONTENT;
-        }
-        if (!params.isAllowEditContent()) {
-            permissions -= PERMISSION_EDIT_CONTENT;
-        }
-        if (!params.isAllowEditAnnotations()) {
-            permissions -= PERMISSION_EDIT_ANNOTATIONS;
-        }
-
-        // Create the encrption key
-        digest.update(prepPassword(params.getUserPassword()));
-        digest.update(oValue);
-        digest.update((byte) (permissions >>> 0));
-        digest.update((byte) (permissions >>> 8));
-        digest.update((byte) (permissions >>> 16));
-        digest.update((byte) (permissions >>> 24));
-        digest.update(getFileID());
-
-        byte [] hash = digest.digest();
-        this.encryptionKey = new byte[5];
-
-        for (int i = 0; i < 5; i++) {
-            this.encryptionKey[i] = hash[i];
-        }
-
-        // Create the user value
-        byte[] uValue = encryptWithKey(prepPassword(""), this.encryptionKey);
-
-        // Create the dictionary
-        this.dictionary = getObjectID()
-                        + "<< /Filter /Standard\n"
-                        + "/V 1\n"
-                        + "/R 2\n"
-                        + "/Length 40\n"
-                        + "/P "  + permissions + "\n"
-                        + "/O " + PDFText.toHex(oValue) + "\n"
-                        + "/U " + PDFText.toHex(uValue) + "\n"
-                        + ">>\n"
-                        + "endobj\n";
+    private PDFEncryptionJCE(int objectNumber, PDFEncryptionParams params, PDFDocument pdf) {
+        setObjectNumber(objectNumber);
+        try {
+            digest = MessageDigest.getInstance("MD5");
+        } catch (NoSuchAlgorithmException e) {
+            throw new UnsupportedOperationException(e.getMessage());
+        }
+        setDocument(pdf);
+        EncryptionInitializer encryptionInitializer = new EncryptionInitializer(params);
+        encryptionInitializer.init();
     }
 
     /**
-     * This method encrypts the passed data using the generated keys.
-     * @param data The data to be encrypted
-     * @param number The block number
-     * @param generation The block generation
-     * @return The encrypted data
-     */
-    public byte[] encryptData(byte[] data, int number, int generation) {
-        if (this.encryptionKey == null) {
-            throw new IllegalStateException("PDF Encryption has not been initialized");
-        }
-        byte[] hash = calcHash(number, generation);
-        return encryptWithHash(data, hash, hash.length);
+     * Creates and returns an encryption object.
+     *
+     * @param objectNumber the object number for the encryption dictionary
+     * @param params the encryption parameters
+     * @param pdf the PDF document to be encrypted
+     * @return the newly created encryption object
+     */
+    public static PDFEncryption make(
+            int objectNumber, PDFEncryptionParams params, PDFDocument pdf) {
+        return new PDFEncryptionJCE(objectNumber, params, pdf);
     }
 
     /** {@inheritDoc} */
@@ -350,63 +466,95 @@ public class PDFEncryptionJCE extends PD
         if (o == null) {
             throw new IllegalStateException("No object number could be obtained for a PDF object");
         }
-        return encryptData(data, o.getObjectNumber(), o.getGeneration());
+        byte[] key = createEncryptionKey(o.getObjectNumber(), o.getGeneration());
+        return encryptWithKey(key, data);
     }
 
-    private byte[] calcHash(int number, int generation) {
-        byte[] hash = new byte[this.encryptionKey.length + 5];
-
-        int i = 0;
-        while (i < this.encryptionKey.length) {
-            hash[i] = this.encryptionKey[i]; i++;
-        }
-
-        hash[i++] = (byte) (number >>> 0);
-        hash[i++] = (byte) (number >>> 8);
-        hash[i++] = (byte) (number >>> 16);
-        hash[i++] = (byte) (generation >>> 0);
-        hash[i++] = (byte) (generation >>> 8);
-        return hash;
-    }
-
-    /**
-     * Creates PDFFilter for the encryption object
-     * @param number The object number
-     * @param generation The objects generation
-     * @return The resulting filter
-     */
-    public PDFFilter makeFilter(int number, int generation) {
-        return new EncryptionFilter(this, number, generation);
-    }
-
-    /**
-     * Adds a PDFFilter to the PDFStream object
-     * @param stream the stream to add an encryption filter to
-     */
+    /** {@inheritDoc} */
     public void applyFilter(AbstractPDFStream stream) {
         stream.getFilterList().addFilter(
-                this.makeFilter(stream.getObjectNumber(), stream.getGeneration()));
+                new EncryptionFilter(stream.getObjectNumber(), stream.getGeneration()));
     }
 
     /**
-     * Represent the object in PDF
+     *  Prepares the encryption dictionary for output to a PDF file.
      *
-     * @return the PDF
+     *  @return the encryption dictionary as a byte array
      */
     public byte[] toPDF() {
-        if (this.dictionary == null) {
-            throw new IllegalStateException("PDF Encryption has not been initialized");
-        }
-
-        return encode(this.dictionary);
+        assert encryptionDictionary != null;
+        return encode(this.encryptionDictionary);
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    /** {@inheritDoc} */
     public String getTrailerEntry() {
+        PDFDocument doc = getDocumentSafely();
+        FileIDGenerator gen = doc.getFileIDGenerator();
         return "/Encrypt " + getObjectNumber() + " "
                     + getGeneration() + " R\n"
-                    + "/ID[" + getFileID(1) + getFileID(2) + "]\n";
+                    + "/ID["
+                    + PDFText.toHex(gen.getOriginalFileID())
+                    + PDFText.toHex(gen.getUpdatedFileID())
+                    + "]\n";
     }
+
+    private static byte[] encryptWithKey(byte[] key, byte[] data) {
+        try {
+            final Cipher c = initCipher(key);
+            return c.doFinal(data);
+        } catch (IllegalBlockSizeException e) {
+            throw new IllegalStateException(e.getMessage());
+        } catch (BadPaddingException e) {
+            throw new IllegalStateException(e.getMessage());
+        }
+    }
+
+    private static Cipher initCipher(byte[] key) {
+        try {
+            Cipher c = Cipher.getInstance("RC4");
+            SecretKeySpec keyspec = new SecretKeySpec(key, "RC4");
+            c.init(Cipher.ENCRYPT_MODE, keyspec);
+            return c;
+        } catch (InvalidKeyException e) {
+            throw new IllegalStateException(e);
+        } catch (NoSuchAlgorithmException e) {
+            throw new UnsupportedOperationException(e);
+        } catch (NoSuchPaddingException e) {
+            throw new UnsupportedOperationException(e);
+        }
+    }
+
+    /**
+     * Applies Algorithm 3.1 from the PDF 1.4 Reference.
+     *
+     * @param objectNumber the object number
+     * @param generationNumber the generation number
+     * @return the key to use for encryption
+     */
+    private byte[] createEncryptionKey(int objectNumber, int generationNumber) {
+        // Step 1 passed in
+        // Step 2
+        byte[] md5Input = prepareMD5Input(objectNumber, generationNumber);
+        // Step 3
+        digest.reset();
+        byte[] hash = digest.digest(md5Input);
+        // Step 4
+        int keyLength = Math.min(16, md5Input.length);
+        byte[] key = new byte[keyLength];
+        System.arraycopy(hash, 0, key, 0, keyLength);
+        return key;
+    }
+
+    private byte[] prepareMD5Input(int objectNumber, int generationNumber) {
+        byte[] md5Input = new byte[encryptionKey.length + 5];
+        System.arraycopy(encryptionKey, 0, md5Input, 0, encryptionKey.length);
+        int i = encryptionKey.length;
+        md5Input[i++] = (byte) (objectNumber >>> 0);
+        md5Input[i++] = (byte) (objectNumber >>> 8);
+        md5Input[i++] = (byte) (objectNumber >>> 16);
+        md5Input[i++] = (byte) (generationNumber >>> 0);
+        md5Input[i++] = (byte) (generationNumber >>> 8);
+        return md5Input;
+    }
+
 }

Modified: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFEncryptionManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFEncryptionManager.java?rev=1177244&r1=1177243&r2=1177244&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFEncryptionManager.java (original)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFEncryptionManager.java Thu Sep 29 09:49:24 2011
@@ -109,16 +109,18 @@ public final class PDFEncryptionManager 
      * Creates a new PDFEncryption instance if PDF encryption is available.
      * @param objnum PDF object number
      * @param params PDF encryption parameters
+     * @param pdf the PDF document to encrypt
      * @return PDFEncryption the newly created instance, null if PDF encryption
      * is unavailable.
      */
-    public static PDFEncryption newInstance(int objnum, PDFEncryptionParams params) {
+    public static PDFEncryption newInstance(int objnum, PDFEncryptionParams params,
+            PDFDocument pdf) {
         try {
-            Class clazz = Class.forName("org.apache.fop.pdf.PDFEncryptionJCE");
+            Class<?> clazz = Class.forName("org.apache.fop.pdf.PDFEncryptionJCE");
             Method makeMethod = clazz.getMethod("make",
-                        new Class[] {int.class, PDFEncryptionParams.class});
+                        new Class[] {int.class, PDFEncryptionParams.class, PDFDocument.class});
             Object obj = makeMethod.invoke(null,
-                        new Object[] {new Integer(objnum), params});
+                        new Object[] {new Integer(objnum), params, pdf});
             return (PDFEncryption)obj;
         } catch (ClassNotFoundException e) {
             if (checkAvailableAlgorithms()) {

Modified: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFEncryptionParams.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFEncryptionParams.java?rev=1177244&r1=1177243&r2=1177244&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFEncryptionParams.java (original)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFEncryptionParams.java Thu Sep 29 09:49:24 2011
@@ -26,10 +26,17 @@ public class PDFEncryptionParams {
 
     private String userPassword = ""; //May not be null
     private String ownerPassword = ""; //May not be null
+
     private boolean allowPrint = true;
     private boolean allowCopyContent = true;
     private boolean allowEditContent = true;
     private boolean allowEditAnnotations = true;
+    private boolean allowFillInForms = true;
+    private boolean allowAccessContent = true;
+    private boolean allowAssembleDocument = true;
+    private boolean allowPrintHq = true;
+
+    private int encryptionLengthInBits = 40;
 
     /**
      * Creates a new instance.
@@ -61,6 +68,25 @@ public class PDFEncryptionParams {
     }
 
     /**
+     * Creates a copy of the given encryption parameters.
+     *
+     * @param source source encryption parameters
+     */
+    public PDFEncryptionParams(PDFEncryptionParams source) {
+        setUserPassword(source.getUserPassword());
+        setOwnerPassword(source.getOwnerPassword());
+        setAllowPrint(source.isAllowPrint());
+        setAllowCopyContent(source.isAllowCopyContent());
+        setAllowEditContent(source.isAllowEditContent());
+        setAllowEditAnnotations(source.isAllowEditAnnotations());
+        setAllowAssembleDocument(source.isAllowAssembleDocument());
+        setAllowAccessContent(source.isAllowAccessContent());
+        setAllowFillInForms(source.isAllowFillInForms());
+        setAllowPrintHq(source.isAllowPrintHq());
+        setEncryptionLengthInBits(source.getEncryptionLengthInBits());
+    }
+
+    /**
      * Indicates whether copying content is allowed.
      * @return true if copying is allowed
      */
@@ -93,6 +119,38 @@ public class PDFEncryptionParams {
     }
 
     /**
+     * Indicates whether revision 3 filling in forms is allowed.
+     * @return true if revision 3 filling in forms is allowed
+     */
+    public boolean isAllowFillInForms() {
+        return allowFillInForms;
+    }
+
+    /**
+     * Indicates whether revision 3 extracting text and graphics is allowed.
+     * @return true if revision 3 extracting text and graphics is allowed
+     */
+    public boolean isAllowAccessContent() {
+        return allowAccessContent;
+    }
+
+    /**
+     * Indicates whether revision 3 assembling document is allowed.
+     * @return true if revision 3 assembling document is allowed
+     */
+    public boolean isAllowAssembleDocument() {
+        return allowAssembleDocument;
+    }
+
+    /**
+     * Indicates whether revision 3 printing to high quality is allowed.
+     * @return true if revision 3 printing to high quality is allowed
+     */
+    public boolean isAllowPrintHq() {
+        return allowPrintHq;
+    }
+
+    /**
      * Returns the owner password.
      * @return the owner password, an empty string if no password applies
      */
@@ -133,7 +191,7 @@ public class PDFEncryptionParams {
     }
 
     /**
-     * Sets the persmission for printing.
+     * Sets the permission for printing.
      * @param allowPrint true if printing is allowed
      */
     public void setAllowPrint(boolean allowPrint) {
@@ -141,6 +199,38 @@ public class PDFEncryptionParams {
     }
 
     /**
+     * Sets whether revision 3 filling in forms is allowed.
+     * @param allowFillInForms true if revision 3 filling in forms is allowed.
+     */
+    public void setAllowFillInForms(boolean allowFillInForms) {
+        this.allowFillInForms = allowFillInForms;
+    }
+
+    /**
+     * Sets whether revision 3 extracting text and graphics is allowed.
+     * @param allowAccessContent true if revision 3 extracting text and graphics is allowed
+     */
+    public void setAllowAccessContent(boolean allowAccessContent) {
+        this.allowAccessContent = allowAccessContent;
+    }
+
+    /**
+     * Sets whether revision 3 assembling document is allowed.
+     * @param allowAssembleDocument true if revision 3 assembling document is allowed
+     */
+    public void setAllowAssembleDocument(boolean allowAssembleDocument) {
+        this.allowAssembleDocument = allowAssembleDocument;
+    }
+
+    /**
+     * Sets whether revision 3 printing to high quality is allowed.
+     * @param allowPrintHq true if revision 3 printing to high quality is allowed
+     */
+    public void setAllowPrintHq(boolean allowPrintHq) {
+        this.allowPrintHq = allowPrintHq;
+    }
+
+    /**
      * Sets the owner password.
      * @param ownerPassword The owner password to set, null or an empty String
      * if no password is applicable
@@ -166,4 +256,21 @@ public class PDFEncryptionParams {
         }
     }
 
+    /**
+     * Returns the encryption length.
+     * @return the encryption length
+     */
+    public int getEncryptionLengthInBits() {
+        return encryptionLengthInBits;
+    }
+
+    /**
+     * Sets the encryption length.
+     *
+     * @param encryptionLength the encryption length
+     */
+    public void setEncryptionLengthInBits(int encryptionLength) {
+        this.encryptionLengthInBits = encryptionLength;
+    }
+
 }

Modified: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFFactory.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFFactory.java?rev=1177244&r1=1177243&r2=1177244&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFFactory.java (original)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFFactory.java Thu Sep 29 09:49:24 2011
@@ -27,6 +27,7 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.MalformedURLException;
+import java.text.DecimalFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.BitSet;
@@ -63,6 +64,7 @@ import org.apache.fop.fonts.truetype.Fon
 import org.apache.fop.fonts.truetype.TTFSubSetFile;
 import org.apache.fop.fonts.type1.PFBData;
 import org.apache.fop.fonts.type1.PFBParser;
+import org.apache.xmlgraphics.xmp.Metadata;
 
 /**
  * This class provides method to create and register PDF objects.
@@ -76,6 +78,8 @@ public class PDFFactory {
 
     private Log log = LogFactory.getLog(PDFFactory.class);
 
+    private int subsetFontCounter = -1;
+
     /**
      * Creates a new PDFFactory.
      * @param document the parent PDFDocument needed to register the generated
@@ -1377,10 +1381,15 @@ public class PDFFactory {
         } else {
             FontType fonttype = metrics.getFontType();
 
-            PDFFontDescriptor pdfdesc = makeFontDescriptor(descriptor);
+            String fontPrefix = descriptor.isSubsetEmbedded() ? createSubsetFontPrefix() : "";
+
+            String subsetFontName = fontPrefix + basefont;
+
+            PDFFontDescriptor pdfdesc = makeFontDescriptor(descriptor, fontPrefix);
 
             PDFFont font = null;
-            font = PDFFont.createFont(fontname, fonttype, basefont, null);
+
+            font = PDFFont.createFont(fontname, fonttype, subsetFontName, null);
             getDocument().registerObject(font);
 
             if (fonttype == FontType.TYPE0) {
@@ -1395,8 +1404,7 @@ public class PDFFactory {
                     = new PDFCIDSystemInfo(cidMetrics.getRegistry(),
                                          cidMetrics.getOrdering(),
                                          cidMetrics.getSupplement());
-                PDFCIDFont cidFont
-                    = new PDFCIDFont(basefont,
+                PDFCIDFont cidFont = new PDFCIDFont(subsetFontName,
                                    cidMetrics.getCIDType(),
                                    cidMetrics.getDefaultWidth(),
                                    getSubsetWidths(cidMetrics), sysInfo,
@@ -1550,18 +1558,35 @@ public class PDFFactory {
         return warray;
     }
 
+    private String createSubsetFontPrefix() {
+        subsetFontCounter++;
+        DecimalFormat counterFormat = new DecimalFormat("00000");
+        String counterString = counterFormat.format(subsetFontCounter);
+
+        // Subset prefix as described in chapter 5.5.3 of PDF 1.4
+        StringBuffer sb = new StringBuffer("E");
+
+        for (char c : counterString.toCharArray()) {
+            // translate numbers to uppercase characters
+            sb.append((char) (c + ('A' - '0')));
+        }
+        sb.append("+");
+        return sb.toString();
+    }
+
     /**
      * make a /FontDescriptor object
      *
      * @param desc the font descriptor
+     * @param fontPrefix the String with which to prefix the font name
      * @return the new PDF font descriptor
      */
-    public PDFFontDescriptor makeFontDescriptor(FontDescriptor desc) {
+    private PDFFontDescriptor makeFontDescriptor(FontDescriptor desc, String fontPrefix) {
         PDFFontDescriptor descriptor = null;
 
         if (desc.getFontType() == FontType.TYPE0) {
             // CID Font
-            descriptor = new PDFCIDFontDescriptor(desc.getEmbedFontName(),
+            descriptor = new PDFCIDFontDescriptor(fontPrefix + desc.getEmbedFontName(),
                                             desc.getFontBBox(),
                                             desc.getCapHeight(),
                                             desc.getFlags(),

Modified: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFObject.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFObject.java?rev=1177244&r1=1177243&r2=1177244&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFObject.java (original)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/pdf/PDFObject.java Thu Sep 29 09:49:24 2011
@@ -112,7 +112,7 @@ public abstract class PDFObject implemen
     }
 
     /**
-     * Returns the object's generation.
+     * Returns this object's generation.
      * @return the PDF Object generation
      */
     public int getGeneration() {

Modified: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java?rev=1177244&r1=1177243&r2=1177244&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java (original)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java Thu Sep 29 09:49:24 2011
@@ -27,7 +27,6 @@ import java.util.List;
 
 import org.apache.avalon.framework.configuration.Configuration;
 import org.apache.avalon.framework.configuration.ConfigurationException;
-
 import org.apache.fop.afp.AFPResourceLevel;
 import org.apache.fop.afp.AFPResourceLevelDefaults;
 import org.apache.fop.afp.fonts.AFPFont;
@@ -258,9 +257,11 @@ public class AFPRendererConfigurator ext
             }
             String name = afpFontCfg.getAttribute("name", characterset);
             CharacterSet characterSet = null;
+            boolean ebcdicDBCS = afpFontCfg.getAttributeAsBoolean("ebcdic-dbcs", false);
+
             try {
-                characterSet = CharacterSetBuilder.getDoubleByteInstance()
-                                .build(characterset, codepage, encoding, accessor);
+                characterSet = CharacterSetBuilder.getDoubleByteInstance().buildDBCS(characterset,
+                        codepage, encoding, ebcdicDBCS, accessor);
             } catch (IOException ioe) {
                 toConfigurationException(codepage, characterset, ioe);
             }

Modified: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/bitmap/BitmapRendererConfigurator.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/bitmap/BitmapRendererConfigurator.java?rev=1177244&r1=1177243&r2=1177244&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/bitmap/BitmapRendererConfigurator.java (original)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/bitmap/BitmapRendererConfigurator.java Thu Sep 29 09:49:24 2011
@@ -115,13 +115,13 @@ public class BitmapRendererConfigurator 
     /** {@inheritDoc} */
     public void setupFontInfo(IFDocumentHandler documentHandler, FontInfo fontInfo)
             throws FOPException {
-        FontManager fontManager = userAgent.getFactory().getFontManager();
+        final FontManager fontManager = userAgent.getFactory().getFontManager();
 
-        Graphics2D graphics2D = Java2DFontMetrics.createFontMetricsGraphics2D();
+        final Java2DFontMetrics java2DFontMetrics = new Java2DFontMetrics();
 
-        List fontCollections = new java.util.ArrayList();
-        fontCollections.add(new Base14FontCollection(graphics2D));
-        fontCollections.add(new InstalledFontCollection(graphics2D));
+        final List fontCollections = new java.util.ArrayList();
+        fontCollections.add(new Base14FontCollection(java2DFontMetrics));
+        fontCollections.add(new InstalledFontCollection(java2DFontMetrics));
 
         Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
         if (cfg != null) {

Modified: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/Base14FontCollection.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/Base14FontCollection.java?rev=1177244&r1=1177243&r2=1177244&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/Base14FontCollection.java (original)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/Base14FontCollection.java Thu Sep 29 09:49:24 2011
@@ -30,14 +30,15 @@ import org.apache.fop.fonts.FontInfo;
  */
 public class Base14FontCollection implements FontCollection {
 
-    private Graphics2D graphics2d = null;
+    /** required when creating new instances of SystemFontMetricsMapper */
+    private final Java2DFontMetrics java2DFontMetrics;
 
     /**
      * Main constructor
-     * @param graphics2d a graphics 2D
+     * @param java2DFontMetrics required when creating new instances of SystemFontMetricsMapper
      */
-    public Base14FontCollection(Graphics2D graphics2d) {
-        this.graphics2d = graphics2d;
+    public Base14FontCollection(Java2DFontMetrics java2DFontMetrics) {
+        this.java2DFontMetrics = java2DFontMetrics;
     }
 
     /**
@@ -56,47 +57,47 @@ public class Base14FontCollection implem
         final int bolditalic = java.awt.Font.BOLD + java.awt.Font.ITALIC;
 
         FontMetricsMapper metric;
-        metric = new SystemFontMetricsMapper("SansSerif", normal, graphics2d);
+        metric = new SystemFontMetricsMapper("SansSerif", normal, java2DFontMetrics);
         // --> goes to  F1
         fontInfo.addMetrics("F1", metric);
-        metric = new SystemFontMetricsMapper("SansSerif", italic, graphics2d);
+        metric = new SystemFontMetricsMapper("SansSerif", italic, java2DFontMetrics);
         // --> goes to  F2
         fontInfo.addMetrics("F2", metric);
-        metric = new SystemFontMetricsMapper("SansSerif", bold, graphics2d);
+        metric = new SystemFontMetricsMapper("SansSerif", bold, java2DFontMetrics);
         // --> goes to  F3
         fontInfo.addMetrics("F3", metric);
-        metric = new SystemFontMetricsMapper("SansSerif", bolditalic, graphics2d);
+        metric = new SystemFontMetricsMapper("SansSerif", bolditalic, java2DFontMetrics);
         // --> goes to  F4
         fontInfo.addMetrics("F4", metric);
 
 
-        metric = new SystemFontMetricsMapper("Serif", normal, graphics2d);
+        metric = new SystemFontMetricsMapper("Serif", normal, java2DFontMetrics);
         // --> goes to  F5
         fontInfo.addMetrics("F5", metric);
-        metric = new SystemFontMetricsMapper("Serif", italic, graphics2d);
+        metric = new SystemFontMetricsMapper("Serif", italic, java2DFontMetrics);
         // --> goes to  F6
         fontInfo.addMetrics("F6", metric);
-        metric = new SystemFontMetricsMapper("Serif", bold, graphics2d);
+        metric = new SystemFontMetricsMapper("Serif", bold, java2DFontMetrics);
         // --> goes to  F7
         fontInfo.addMetrics("F7", metric);
-        metric = new SystemFontMetricsMapper("Serif", bolditalic, graphics2d);
+        metric = new SystemFontMetricsMapper("Serif", bolditalic, java2DFontMetrics);
         // --> goes to  F8
         fontInfo.addMetrics("F8", metric);
 
-        metric = new SystemFontMetricsMapper("MonoSpaced", normal, graphics2d);
+        metric = new SystemFontMetricsMapper("MonoSpaced", normal, java2DFontMetrics);
         // --> goes to  F9
         fontInfo.addMetrics("F9", metric);
-        metric = new SystemFontMetricsMapper("MonoSpaced", italic, graphics2d);
+        metric = new SystemFontMetricsMapper("MonoSpaced", italic, java2DFontMetrics);
         // --> goes to  F10
         fontInfo.addMetrics("F10", metric);
-        metric = new SystemFontMetricsMapper("MonoSpaced", bold, graphics2d);
+        metric = new SystemFontMetricsMapper("MonoSpaced", bold, java2DFontMetrics);
         // --> goes to  F11
         fontInfo.addMetrics("F11", metric);
-        metric = new SystemFontMetricsMapper("MonoSpaced", bolditalic, graphics2d);
+        metric = new SystemFontMetricsMapper("MonoSpaced", bolditalic, java2DFontMetrics);
         // --> goes to  F12
         fontInfo.addMetrics("F12", metric);
 
-        metric = new SystemFontMetricsMapper("Serif", normal, graphics2d);
+        metric = new SystemFontMetricsMapper("Serif", normal, java2DFontMetrics);
         //"Symbol" doesn't seem to work here, but "Serif" does the job just fine. *shrug*
         // --> goes to  F13 and F14
         fontInfo.addMetrics("F13", metric);

Modified: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/InstalledFontCollection.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/InstalledFontCollection.java?rev=1177244&r1=1177243&r2=1177244&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/InstalledFontCollection.java (original)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/InstalledFontCollection.java Thu Sep 29 09:49:24 2011
@@ -38,10 +38,10 @@ public class InstalledFontCollection imp
 
     private static Log log = LogFactory.getLog(InstalledFontCollection.class);
 
-    private static final Set HARDCODED_FONT_NAMES;
+    private static final Set<String> HARDCODED_FONT_NAMES;
 
     static {
-        HARDCODED_FONT_NAMES = new java.util.HashSet();
+        HARDCODED_FONT_NAMES = new java.util.HashSet<String>();
         HARDCODED_FONT_NAMES.add("any");
         HARDCODED_FONT_NAMES.add("sans-serif");
         HARDCODED_FONT_NAMES.add("serif");
@@ -57,15 +57,16 @@ public class InstalledFontCollection imp
         HARDCODED_FONT_NAMES.add("Computer-Modern-Typewriter");
     }
 
-    private Graphics2D graphics2D = null;
+    /** Required by new instances of FontMetricsMapper */
+    private final Java2DFontMetrics java2DFontMetrics;
 
     /**
      * Main constructor
      *
-     * @param graphics2D a graphics 2D
+     * @param java2DFontMetrics required by new instances of FontMetricsMapper
      */
-    public InstalledFontCollection(Graphics2D graphics2D) {
-        this.graphics2D  = graphics2D;
+    public InstalledFontCollection(Java2DFontMetrics java2DFontMetrics) {
+        this.java2DFontMetrics  = java2DFontMetrics;
     }
 
     /**
@@ -98,7 +99,7 @@ public class InstalledFontCollection imp
             num++;
             String fontKey = "F" + num;
             int style = convertToAWTFontStyle(guessedStyle, guessedWeight);
-            addFontMetricsMapper(fontInfo, f.getName(), fontKey, graphics2D, style);
+            addFontMetricsMapper(fontInfo, f.getName(), fontKey, java2DFontMetrics, style);
 
             //Register appropriate font triplets matching the font. Two different strategies:
             //Example: "Arial Bold", normal, normal
@@ -120,8 +121,8 @@ public class InstalledFontCollection imp
     }
 
     private static void addFontMetricsMapper(FontInfo fontInfo, String family, String fontKey,
-            Graphics2D graphics, int style) {
-        FontMetricsMapper metric = new SystemFontMetricsMapper(family, style, graphics);
+            Java2DFontMetrics java2DFontMetrics, int style) {
+        FontMetricsMapper metric = new SystemFontMetricsMapper(family, style, java2DFontMetrics);
         fontInfo.addMetrics(fontKey, metric);
     }
 

Modified: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/Java2DFontMetrics.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/Java2DFontMetrics.java?rev=1177244&r1=1177243&r2=1177244&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/Java2DFontMetrics.java (original)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/Java2DFontMetrics.java Thu Sep 29 09:49:24 2011
@@ -109,13 +109,13 @@ public class Java2DFontMetrics {
     /**
      * Temp graphics object needed to get the font metrics
      */
-    private Graphics2D graphics;
+    private final Graphics2D graphics;
 
     /**
      * Creates a Graphics2D object for the sole purpose of getting font metrics.
      * @return a Graphics2D object
      */
-    public static Graphics2D createFontMetricsGraphics2D() {
+    private static Graphics2D createFontMetricsGraphics2D() {
         BufferedImage fontImage = new BufferedImage(100, 100,
                 BufferedImage.TYPE_INT_RGB);
         Graphics2D graphics2D = fontImage.createGraphics();
@@ -127,11 +127,9 @@ public class Java2DFontMetrics {
 
     /**
      * Constructs a new Font-metrics.
-     * @param graphics a temp graphics object - this is needed  so
-     * that we can get an instance of java.awt.FontMetrics
      */
-    public Java2DFontMetrics(Graphics2D graphics) {
-        this.graphics = graphics;
+    public Java2DFontMetrics() {
+        this.graphics = createFontMetricsGraphics2D();
     }
 
     /**
@@ -142,7 +140,7 @@ public class Java2DFontMetrics {
      * @param size font size
      * @return ascent in milliponts
      */
-    public synchronized int getMaxAscent(String family, int style, int size) {
+    public int getMaxAscent(String family, int style, int size) {
         setFont(family, style, size);
         return Math.round(lineMetrics.getAscent() * FONT_FACTOR);
     }
@@ -155,7 +153,7 @@ public class Java2DFontMetrics {
      * @param size font size
      * @return ascent in milliponts
      */
-    public synchronized int getAscender(String family, int style, int size) {
+    public int getAscender(String family, int style, int size) {
         setFont(family, style, size);
         return ascender * 1000;
 
@@ -193,7 +191,7 @@ public class Java2DFontMetrics {
      * @param size font size
      * @return capital height in millipoints
      */
-    public synchronized int getCapHeight(String family, int style, int size) {
+    public int getCapHeight(String family, int style, int size) {
         // currently just gets Ascent value but maybe should use
         // getMaxAcent() at some stage
         return getAscender(family, style, size);
@@ -207,7 +205,7 @@ public class Java2DFontMetrics {
      * @param size font size
      * @return descent in milliponts
      */
-    public synchronized int getDescender(String family, int style, int size) {
+    public int getDescender(String family, int style, int size) {
         setFont(family, style, size);
         return descender * 1000;
     }
@@ -220,7 +218,7 @@ public class Java2DFontMetrics {
      * @param size font size
      * @return font height in milliponts
      */
-    public synchronized int getXHeight(String family, int style, int size) {
+    public int getXHeight(String family, int style, int size) {
         setFont(family, style, size);
         return xHeight * 1000;
     }
@@ -234,7 +232,7 @@ public class Java2DFontMetrics {
      * @param size font size
      * @return character width in millipoints
      */
-    public synchronized int width(int i, String family, int style, int size) {
+    public int width(int i, String family, int style, int size) {
         int w;
         setFont(family, style, size);
         w = internalCharWidth(i) * 1000;
@@ -256,7 +254,7 @@ public class Java2DFontMetrics {
      * @param size font size
      * @return array of character widths in millipoints
      */
-    public synchronized int[] getWidths(String family, int style, int size) {
+    public int[] getWidths(String family, int style, int size) {
         int i;
 
         if (width == null) {
@@ -351,7 +349,7 @@ public class Java2DFontMetrics {
      * @param size font size
      * @return font with the desired characeristics.
      */
-    public synchronized java.awt.Font getFont(String family, int style, int size) {
+    public java.awt.Font getFont(String family, int style, int size) {
         setFont(family, style, size);
         return f1;
         /*
@@ -372,7 +370,7 @@ public class Java2DFontMetrics {
      * @param c the glyph to check
      * @return true if the character is supported
      */
-    public synchronized boolean hasChar(String family, int style, int size, char c) {
+    public boolean hasChar(String family, int style, int size, char c) {
         setFont(family, style, size);
         return f1.canDisplay(c);
     }

Modified: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/Java2DRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/Java2DRenderer.java?rev=1177244&r1=1177243&r2=1177244&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/Java2DRenderer.java (original)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/Java2DRenderer.java Thu Sep 29 09:49:24 2011
@@ -171,11 +171,11 @@ public abstract class Java2DRenderer ext
         //Don't call super.setupFontInfo() here! Java2D needs a special font setup
         // create a temp Image to test font metrics on
         this.fontInfo = inFontInfo;
-        Graphics2D graphics2D = Java2DFontMetrics.createFontMetricsGraphics2D();
+        final Java2DFontMetrics java2DFontMetrics = new Java2DFontMetrics();
 
         FontCollection[] fontCollections = new FontCollection[] {
-                new Base14FontCollection(graphics2D),
-                new InstalledFontCollection(graphics2D),
+                new Base14FontCollection(java2DFontMetrics),
+                new InstalledFontCollection(java2DFontMetrics),
                 new ConfiguredFontCollection(getFontResolver(), getFontList())
         };
         userAgent.getFactory().getFontManager().setup(

Modified: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/Java2DUtil.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/Java2DUtil.java?rev=1177244&r1=1177243&r2=1177244&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/Java2DUtil.java (original)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/Java2DUtil.java Thu Sep 29 09:49:24 2011
@@ -44,12 +44,12 @@ public final class Java2DUtil {
      */
     public static FontInfo buildDefaultJava2DBasedFontInfo(
             FontInfo fontInfo, FOUserAgent userAgent) {
-        Graphics2D graphics2D = Java2DFontMetrics.createFontMetricsGraphics2D();
+        Java2DFontMetrics java2DFontMetrics = new Java2DFontMetrics();
 
         FontManager fontManager = userAgent.getFactory().getFontManager();
         FontCollection[] fontCollections = new FontCollection[] {
-                new org.apache.fop.render.java2d.Base14FontCollection(graphics2D),
-                new InstalledFontCollection(graphics2D)
+                new org.apache.fop.render.java2d.Base14FontCollection(java2DFontMetrics),
+                new InstalledFontCollection(java2DFontMetrics)
         };
 
         FontInfo fi = (fontInfo != null ? fontInfo : new FontInfo());

Modified: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java?rev=1177244&r1=1177243&r2=1177244&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java (original)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java Thu Sep 29 09:49:24 2011
@@ -42,7 +42,7 @@ public class SystemFontMetricsMapper ext
      * This is a Java2DFontMetrics that does the real calculation.
      * It is only one class that dynamically determines the font-size.
      */
-    private static Java2DFontMetrics metric = null;
+    private final Java2DFontMetrics java2DFontMetrics;
 
     /**
      * The java name of the font.
@@ -60,15 +60,14 @@ public class SystemFontMetricsMapper ext
      * Constructs a new Font-metrics.
      * @param family the family name of the font (java value)
      * @param style the java type style value of the font
-     * @param graphics a Graphics2D object - this is needed  so
-     * that we can get an instance of java.awt.FontMetrics
+     * @param java2DFontMetrics metric calculations delegated to this
      */
-    public SystemFontMetricsMapper(String family, int style, Graphics2D graphics) {
+    public SystemFontMetricsMapper(String family, int style, Java2DFontMetrics java2DFontMetrics) {
         this.family = family;
+
         this.style = style;
-        if (metric == null) {
-            metric = new Java2DFontMetrics(graphics);
-        }
+
+        this.java2DFontMetrics = java2DFontMetrics;
     }
 
     /** {@inheritDoc} */
@@ -104,42 +103,42 @@ public class SystemFontMetricsMapper ext
      * {@inheritDoc}
      */
     public int getMaxAscent(int size) {
-        return metric.getMaxAscent(family, style, size);
+        return java2DFontMetrics.getMaxAscent(family, style, size);
     }
 
     /**
      * {@inheritDoc}
      */
     public int getAscender(int size) {
-        return metric.getAscender(family, style, size);
+        return java2DFontMetrics.getAscender(family, style, size);
     }
 
     /**
      * {@inheritDoc}
      */
     public int getCapHeight(int size) {
-        return metric.getCapHeight(family, style, size);
+        return java2DFontMetrics.getCapHeight(family, style, size);
     }
 
     /**
      * {@inheritDoc}
      */
     public int getDescender(int size) {
-        return metric.getDescender(family, style, size);
+        return java2DFontMetrics.getDescender(family, style, size);
     }
 
     /**
      * {@inheritDoc}
      */
     public int getXHeight(int size) {
-        return metric.getXHeight(family, style, size);
+        return java2DFontMetrics.getXHeight(family, style, size);
     }
 
     /**
      * {@inheritDoc}
      */
     public int getWidth(int i, int size) {
-        return metric.width(i, family, style, size);
+        return java2DFontMetrics.width(i, family, style, size);
     }
 
 
@@ -147,14 +146,14 @@ public class SystemFontMetricsMapper ext
      * {@inheritDoc}
      */
     public int[] getWidths() {
-        return metric.getWidths(family, style, Java2DFontMetrics.FONT_SIZE);
+        return java2DFontMetrics.getWidths(family, style, Java2DFontMetrics.FONT_SIZE);
     }
 
     /**
      * {@inheritDoc}
      */
     public java.awt.Font getFont(int size) {
-        return metric.getFont(family, style, size);
+        return java2DFontMetrics.getFont(family, style, size);
     }
 
     /**
@@ -183,7 +182,7 @@ public class SystemFontMetricsMapper ext
 
     /** {@inheritDoc} */
     public boolean hasChar(char c) {
-        return metric.hasChar(family, style, Java2DFontMetrics.FONT_SIZE, c);
+        return java2DFontMetrics.hasChar(family, style, Java2DFontMetrics.FONT_SIZE, c);
     }
 
 }

Modified: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java?rev=1177244&r1=1177243&r2=1177244&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java (original)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java Thu Sep 29 09:49:24 2011
@@ -108,11 +108,10 @@ public class PCLRendererConfigurator ext
                 throws FOPException {
         FontManager fontManager = userAgent.getFactory().getFontManager();
 
-        Graphics2D graphics2D = Java2DFontMetrics.createFontMetricsGraphics2D();
-
-        List fontCollections = new java.util.ArrayList();
-        fontCollections.add(new Base14FontCollection(graphics2D));
-        fontCollections.add(new InstalledFontCollection(graphics2D));
+        final Java2DFontMetrics java2DFontMetrics = new Java2DFontMetrics();
+        final List fontCollections = new java.util.ArrayList();
+        fontCollections.add(new Base14FontCollection(java2DFontMetrics));
+        fontCollections.add(new InstalledFontCollection(java2DFontMetrics));
 
         Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
         if (cfg != null) {

Modified: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/pdf/PDFConfigurationConstants.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/pdf/PDFConfigurationConstants.java?rev=1177244&r1=1177243&r2=1177244&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/pdf/PDFConfigurationConstants.java (original)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/pdf/PDFConfigurationConstants.java Thu Sep 29 09:49:24 2011
@@ -38,6 +38,36 @@ public interface PDFConfigurationConstan
     String NO_EDIT_CONTENT = "noedit";
     /** PDF encryption parameter: Forbids annotations, datatype: Boolean or "true"/"false" */
     String NO_ANNOTATIONS = "noannotations";
+
+    /**
+     * PDF encryption parameter: Forbids filling in existing interactive forms, datatype:
+     * Boolean or "true"/"false"
+     */
+    String NO_FILLINFORMS = "nofillinforms";
+
+    /**
+     * PDF encryption parameter: Forbids extracting text and graphics, datatype: Boolean
+     * or "true"/"false"
+     */
+    String NO_ACCESSCONTENT = "noaccesscontent";
+
+    /**
+     * PDF encryption parameter: Forbids assembling document, datatype: Boolean or
+     * "true"/"false"
+     */
+    String NO_ASSEMBLEDOC = "noassembledoc";
+
+    /**
+     * PDF encryption parameter: Forbids printing to high quality, datatype: Boolean or
+     * "true"/"false"
+     */
+    String NO_PRINTHQ = "noprinthq";
+
+    /**
+     * PDF encryption length parameter: must be a multiple of 8 between 40 and 128,
+     * default value 40, datatype: int.
+     */
+    String ENCRYPTION_LENGTH = "encryption-length";
     /** Rendering Options key for the PDF/A mode. */
     String PDF_A_MODE = "pdf-a-mode";
     /** Rendering Options key for the PDF/X mode. */

Modified: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/pdf/PDFEventProducer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/pdf/PDFEventProducer.java?rev=1177244&r1=1177243&r2=1177244&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/pdf/PDFEventProducer.java (original)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/pdf/PDFEventProducer.java Thu Sep 29 09:49:24 2011
@@ -65,4 +65,14 @@ public interface PDFEventProducer extend
      * @event.severity WARN
      */
     void nonStandardStructureType(Object source, String fo, String type, String fallback);
+
+    /**
+     * The encryption length must be a multiple of 8 between 40 and 128.
+     *
+     * @param source the event source
+     * @param originalValue requested encryption length
+     * @param correctedValue corrected encryption length
+     * @event.severity WARN
+     */
+    void incorrectEncryptionLength(Object source, int originalValue, int correctedValue);
 }

Modified: xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/pdf/PDFEventProducer.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/pdf/PDFEventProducer.xml?rev=1177244&r1=1177243&r2=1177244&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/pdf/PDFEventProducer.xml (original)
+++ xmlgraphics/fop/branches/Temp_ComplexScripts/src/java/org/apache/fop/render/pdf/PDFEventProducer.xml Thu Sep 29 09:49:24 2011
@@ -2,4 +2,5 @@
 <catalogue xml:lang="en">
   <message key="nonFullyResolvedLinkTargets">{count} link target{count,equals,1,,s} could not be fully resolved and now point{count,equals,1,,s} to the top of the page or {count,equals,1,is,are} dysfunctional.</message>
   <message key="nonStandardStructureType">‘{type}’ is not a standard structure type defined by the PDF Reference. Falling back to ‘{fallback}’.</message>
+  <message key="incorrectEncryptionLength">Encryption length must be a multiple of 8 between 40 and 128. Setting encryption length to {correctedValue} instead of {originalValue}.</message>
 </catalogue>



---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org