FOP-2951: Add uniquename to xobj form

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop-pdf-images/trunk@1879364 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/MergeCFFFonts.java b/src/java/org/apache/fop/render/pdf/pdfbox/MergeCFFFonts.java
index c3e6881..f44c9f1 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/MergeCFFFonts.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/MergeCFFFonts.java
@@ -44,6 +44,7 @@
 
 import org.apache.fop.fonts.cff.CFFDataReader;
 import org.apache.fop.fonts.truetype.FontFileReader;
+import org.apache.fop.pdf.PDFDocument;
 
 public class MergeCFFFonts extends OTFSubSetFile implements MergeFonts {
     protected List<Map<Integer, Integer>> subsetGlyphsList = new ArrayList<Map<Integer, Integer>>();
@@ -338,7 +339,7 @@
             } else {
                 String notice = (String)fileFont.getTopDict().get("Notice");
                 if (notice != null && !(fileFont instanceof CFFCIDFont)) {
-                    stringIndexData.add(notice.getBytes("ISO-8859-1"));
+                    stringIndexData.add(notice.getBytes(PDFDocument.ENCODING));
                 }
             }
             stringIndexData.add(embeddedName.getBytes("UTF-8"));
@@ -346,7 +347,8 @@
         } else {
             String notice = (String)fileFont.getTopDict().get("Notice");
             if (notice != null) {
-                writeIndex(Arrays.<byte[]>asList(notice.getBytes("ISO-8859-1"), embeddedName.getBytes("UTF-8")));
+                writeIndex(Arrays.<byte[]>asList(notice.getBytes(PDFDocument.ENCODING),
+                        embeddedName.getBytes("UTF-8")));
             } else {
                 List<byte[]> sindex = new ArrayList<byte[]>();
                 sindex.add(cffReader.getStringIndex().getData());
diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/MergeFontsPDFWriter.java b/src/java/org/apache/fop/render/pdf/pdfbox/MergeFontsPDFWriter.java
index 25012ce..4024431 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/MergeFontsPDFWriter.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/MergeFontsPDFWriter.java
@@ -56,9 +56,9 @@
 import org.apache.fop.fonts.Typeface;
 import org.apache.fop.fonts.truetype.OTFSubSetFile;
 
+import org.apache.fop.pdf.PDFDocument;
 import org.apache.fop.pdf.PDFText;
 
-
 public class MergeFontsPDFWriter extends PDFWriter {
     protected static final Log log = LogFactory.getLog(MergeFontsPDFWriter.class);
     private COSDictionary fonts;
@@ -223,7 +223,7 @@
     }
 
     private String getString(COSString s) throws UnsupportedEncodingException {
-        String encoding = "ISO-8859-1";
+        String encoding = PDFDocument.ENCODING;
         byte[] data = s.getBytes();
         int start = 0;
         if (data.length > 2) {
diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java b/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java
index a8ac934..e6d11f5 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java
@@ -92,7 +92,8 @@
     private Map<Integer, PDFArray> pageNumbers;
     private Collection<String> parentFonts = new ArrayList<String>();
 
-    private int currentMCID;
+    protected int currentMCID;
+    protected UniqueName uniqueName;
 
     /**
      * Creates a new PDFBoxAdapter.
@@ -179,16 +180,16 @@
     public Object createStreamFromPDFBoxPage(PDDocument sourceDoc, PDPage page, String key,
                                                      AffineTransform atdoc, FontInfo fontinfo, Rectangle pos)
         throws IOException {
+        COSDictionary sourcePageResources = getResources(page);
+        uniqueName = new UniqueName(key, sourcePageResources, pdfDoc.isFormXObjectEnabled());
         handleAnnotations(sourceDoc, page, atdoc);
         if (pageNumbers.containsKey(targetPage.getPageIndex())) {
             pageNumbers.get(targetPage.getPageIndex()).set(0, targetPage.makeReference());
         }
-        COSDictionary sourcePageResources = getResources(page);
         PDStream pdStream = getContents(page);
 
         COSDictionary fonts = (COSDictionary)sourcePageResources.getDictionaryObject(COSName.FONT);
         COSDictionary fontsBackup = null;
-        UniqueName uniqueName = new UniqueName(key, sourcePageResources);
         String newStream = null;
         if (fonts != null && pdfDoc.isMergeFontsEnabled()) {
             fontsBackup = new COSDictionary(fonts);
@@ -298,6 +299,23 @@
         return pdStream;
     }
 
+    private void updateMergeFontInfo(PDFDictionary pageResources, FontInfo fontinfo) {
+        PDFDictionary fontDict = (PDFDictionary)pageResources.get("Font");
+        if (fontDict != null && pdfDoc.isMergeFontsEnabled()) {
+            for (Map.Entry<String, Typeface> fontEntry : fontinfo.getUsedFonts().entrySet()) {
+                Typeface font = fontEntry.getValue();
+                if (font instanceof FOPPDFFont) {
+                    FOPPDFFont pdfFont = (FOPPDFFont)font;
+                    if (pdfFont.getRef() == null) {
+                        pdfFont.setRef(new PDFDictionary());
+                        pdfDoc.assignObjectNumber(pdfFont.getRef());
+                    }
+                    fontDict.put(fontEntry.getKey(), pdfFont.getRef());
+                }
+            }
+        }
+    }
+
     private PDFFormXObject getFormXObject(PDFDictionary pageResources, PDFStream pageStream, String key, PDPage page)
         throws IOException {
         if (pdfDoc.isMergeFontsEnabled()) {
@@ -401,8 +419,8 @@
             PDFDictionary target = (PDFDictionary) pageResources.get("XObject");
             for (COSName entry : xobj.keySet()) {
                 if (newXObj.containsKey(entry)) {
-                    PDFStream s = (PDFStream) target.get(entry.getName());
-                    s.setData(newXObj.get(entry).getBytes("ISO-8859-1"));
+                    PDFStream s = (PDFStream) target.get(uniqueName.getName(entry));
+                    s.setData(newXObj.get(entry).getBytes(PDFDocument.ENCODING));
                     PDFDictionary xobjr = (PDFDictionary) s.get("Resources");
                     xobjr.put("Font", pageResources.get("Font"));
                 }
diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/PDFCloner.java b/src/java/org/apache/fop/render/pdf/pdfbox/PDFCloner.java
index dae4738..52fb7c2 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/PDFCloner.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/PDFCloner.java
@@ -40,9 +40,11 @@
 import org.apache.pdfbox.cos.COSStream;
 import org.apache.pdfbox.cos.COSString;
 import org.apache.pdfbox.pdmodel.common.COSObjectable;
+import org.apache.pdfbox.pdmodel.common.PDStream;
 
 import org.apache.fop.pdf.PDFArray;
 import org.apache.fop.pdf.PDFDictionary;
+import org.apache.fop.pdf.PDFDocument;
 import org.apache.fop.pdf.PDFName;
 import org.apache.fop.pdf.PDFNumber;
 import org.apache.fop.pdf.PDFObject;
@@ -142,7 +144,11 @@
         cacheClonedObject(keyBase, newDict);
         for (Map.Entry<COSName, COSBase> e : dic.entrySet()) {
             if (!exclude.contains(e.getKey())) {
-                newDict.put(e.getKey().getName(), cloneForNewDocument(e.getValue(), e.getValue(), exclude));
+                String name = e.getKey().getName();
+                if (adapter.uniqueName != null) {
+                    name = adapter.uniqueName.getName(e.getKey());
+                }
+                newDict.put(name, cloneForNewDocument(e.getValue(), e.getValue(), exclude));
             }
         }
         return newDict;
@@ -179,7 +185,23 @@
         }
         PDFStream stream = new PDFStream();
         OutputStream out = stream.getBufferOutputStream();
-        IOUtils.copyLarge(in, out);
+        if (originalStream.getItem(COSName.SUBTYPE) == COSName.FORM && adapter.uniqueName != null) {
+            PDFWriter writer = new PDFWriter(adapter.uniqueName, adapter.currentMCID);
+            try {
+                String newStream = writer.writeText(new PDStream(originalStream));
+                if (writer.keyUsed) {
+                    filter = adapter.FILTER_FILTER;
+                    out.write(newStream.getBytes(PDFDocument.ENCODING));
+                    out.close();
+                    in = null;
+                }
+            } catch (IOException e) {
+                //ignore
+            }
+        }
+        if (in != null) {
+            IOUtils.copyLarge(in, out);
+        }
         adapter.transferDict(originalStream, stream, filter);
         return cacheClonedObject(keyBase, stream);
     }
diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/PDFString.java b/src/java/org/apache/fop/render/pdf/pdfbox/PDFString.java
index dbee9de..32cfa76 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/PDFString.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/PDFString.java
@@ -59,7 +59,7 @@
      */
     public String getString() {
         if (this.text == null) {
-            String encoding = "ISO-8859-1";
+            String encoding = PDFDocument.ENCODING;
             int start = 0;
             if (this.binary.length > 2) {
                 if (this.binary[0] == (byte)0xFF && this.binary[1] == (byte)0xFE) {
@@ -103,7 +103,7 @@
                     binary[1] = (byte)0xFF;
                     System.arraycopy(data, 0, binary, 2, data.length);
                 } else {
-                    byte[] data = this.text.getBytes("ISO-8859-1");
+                    byte[] data = this.text.getBytes(PDFDocument.ENCODING);
                     binary = new byte[data.length];
                     System.arraycopy(data, 0, binary, 0, data.length);
                 }
diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/PDFWriter.java b/src/java/org/apache/fop/render/pdf/pdfbox/PDFWriter.java
index e96bdb3..50502fd 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/PDFWriter.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/PDFWriter.java
@@ -39,6 +39,7 @@
 import org.apache.pdfbox.pdfparser.PDFStreamParser;
 import org.apache.pdfbox.pdmodel.common.PDStream;
 
+import org.apache.fop.pdf.PDFDocument;
 
 public class PDFWriter {
     private DecimalFormat df = new DecimalFormat("#.####", new DecimalFormatSymbols(Locale.US));
@@ -46,6 +47,7 @@
     protected StringBuilder s = new StringBuilder();
     protected UniqueName key;
     private int currentMCID;
+    protected boolean keyUsed;
 
     public PDFWriter(UniqueName key, int currentMCID) {
         this.key = key;
@@ -69,7 +71,7 @@
                         arguments.add(cn.getValue());
                     }
                     readPDFArguments(op, arguments);
-                    s.append("ID " + new String(op.getImageData(), "ISO-8859-1"));
+                    s.append("ID " + new String(op.getImageData(), PDFDocument.ENCODING));
                     arguments.clear();
                     s.append("EI\n");
                 }
@@ -102,8 +104,12 @@
             }
         } else if (c instanceof COSName) {
             COSName cn = (COSName)c;
-            s.append("/" + key.getName(cn));
+            String name = key.getName(cn);
+            s.append("/" + name);
             s.append(" ");
+            if (!name.equals(cn.getName())) {
+                keyUsed = true;
+            }
         } else if (c instanceof COSString) {
             s.append("<" + ((COSString) c).toHexString() + ">");
         } else if (c instanceof COSArray) {
diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/UniqueName.java b/src/java/org/apache/fop/render/pdf/pdfbox/UniqueName.java
index 4bd61b6..c55b716 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/UniqueName.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/UniqueName.java
@@ -19,6 +19,7 @@
 package org.apache.fop.render.pdf.pdfbox;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 import org.apache.pdfbox.cos.COSBase;
@@ -30,9 +31,14 @@
     private String key;
     private List<COSName> resourceNames;
 
-    public UniqueName(String key, COSDictionary sourcePageResources) {
-        this.key = Integer.toString(key.hashCode());
-        resourceNames = getResourceNames(sourcePageResources);
+    public UniqueName(String key, COSDictionary sourcePageResources, boolean disable) {
+        if (disable) {
+            resourceNames = Collections.emptyList();
+        } else {
+            key = key.split("#")[0];
+            this.key = Integer.toString(key.hashCode());
+            resourceNames = getResourceNames(sourcePageResources);
+        }
     }
 
     protected String getName(COSName cn) {
diff --git a/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java b/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
index 29e961f..84f36f4 100644
--- a/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
+++ b/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
@@ -28,10 +28,12 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.URI;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.junit.Assert;
@@ -657,4 +659,27 @@
         formXObject.output(bos);
         Assert.assertTrue(bos.toString("UTF-8").contains("/Type /XObject"));
     }
+
+    @Test
+    public void testRewriteOfForms() throws Exception {
+        PDFDocument pdfdoc = new PDFDocument("");
+        PDFPage pdfpage = getPDFPage(pdfdoc);
+        pdfpage.setDocument(pdfdoc);
+        pdfpage.setObjectNumber(1);
+        PDFBoxAdapter adapter = new PDFBoxAdapter(pdfpage, new HashMap(), new HashMap<Integer, PDFArray>());
+        PDDocument doc = PDDocument.load(new File(ACCESSIBLERADIOBUTTONS));
+        PDPage page = doc.getPage(0);
+        AffineTransform at = new AffineTransform();
+        Rectangle r = new Rectangle(0, 1650, 842000, 595000);
+        adapter.createStreamFromPDFBoxPage(doc, page, "key", at, null, r);
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        Map<String, List<String>> filterMap = new HashMap<String, List<String>>();
+        List<String> filterList = new ArrayList<String>();
+        filterList.add("null");
+        filterMap.put("default", filterList);
+        pdfdoc.setFilterMap(filterMap);
+        pdfdoc.output(os);
+        Assert.assertTrue(os.toString("UTF-8").contains("/F15106079 12 Tf"));
+        doc.close();
+    }
 }