]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
fixes problem of links not working after data output
authorKeiron Liddle <keiron@apache.org>
Mon, 11 Nov 2002 08:50:54 +0000 (08:50 +0000)
committerKeiron Liddle <keiron@apache.org>
Mon, 11 Nov 2002 08:50:54 +0000 (08:50 +0000)
annotations now explicitly added
fixed font name lookup error so now font output only once
pdf renderer uses context to output things better
added Form XObject
add transition dictionary

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

src/org/apache/fop/pdf/PDFDocument.java
src/org/apache/fop/pdf/PDFFormXObject.java [new file with mode: 0644]
src/org/apache/fop/pdf/PDFPage.java
src/org/apache/fop/pdf/PDFResourceContext.java
src/org/apache/fop/pdf/PDFRoot.java
src/org/apache/fop/pdf/TransitionDictionary.java [new file with mode: 0644]
src/org/apache/fop/render/pdf/PDFRenderer.java
src/org/apache/fop/render/pdf/PDFXMLHandler.java
src/org/apache/fop/svg/PDFDocumentGraphics2D.java
src/org/apache/fop/svg/PDFGraphics2D.java

index dc1636381faf32212ecc602388de014f33fbbe8f..f4b115770438030bd29258211db3dde3777cce67 100644 (file)
@@ -1004,7 +1004,7 @@ public class PDFDocument {
             PDFFont font = new PDFFont(++this.objectcount, fontname,
                                        PDFFont.TYPE1, basefont, encoding);
             this.objects.add(font);
-            fontMap.put(basefont, font);
+            fontMap.put(fontname, font);
             return font;
         } else {
             byte subtype = PDFFont.TYPE1;
@@ -1071,7 +1071,7 @@ public class PDFDocument {
                                      makeArray(metrics.getWidths(1)));
             }
 
-            fontMap.put(basefont, font);
+            fontMap.put(fontname, font);
 
             return font;
         }
@@ -1190,6 +1190,19 @@ public class PDFDocument {
         return xObject;
     }
 
+    public PDFFormXObject addFormXObject(PDFResourceContext res, PDFStream cont, PDFResources formres, String key) {
+        PDFFormXObject xObject;
+        xObject = new PDFFormXObject(++this.objectcount, ++this.xObjectCount,
+                                 cont, formres.referencePDF());
+        this.objects.add(xObject);
+        this.resources.addXObject(xObject);
+        if (res != null) {
+            res.getPDFResources().addXObject(xObject);
+        }
+        return xObject;
+
+    }
+
     /**
      * make a /Page object
      *
@@ -1357,10 +1370,18 @@ public class PDFDocument {
          * to the list of objects
          */
         PDFAnnotList obj = new PDFAnnotList(++this.objectcount);
-        this.objects.add(obj);
         return obj;
     }
 
+    /**
+     * Add an annotation list object to the pdf document
+     *
+     * @param obj the annotation list to add 
+     */ 
+    public void addAnnotList(PDFAnnotList obj) {
+        this.objects.add(obj);
+    }
+
     /**
      * Get the root Outlines object. This method does not write
      * the outline to the PDF document, it simply creates a
diff --git a/src/org/apache/fop/pdf/PDFFormXObject.java b/src/org/apache/fop/pdf/PDFFormXObject.java
new file mode 100644 (file)
index 0000000..34cdc72
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * $Id$
+ * Copyright (C) 2001-2002 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.pdf;
+
+// Java
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * PDF Form XObject
+ *
+ * A derivative of the PDFXObject, is a PDF Stream that has not only a
+ * dictionary but a stream of image data.
+ */
+public class PDFFormXObject extends PDFXObject {
+    private PDFStream contents;
+    private String resRef;
+
+    /**
+     * create a FormXObject with the given number and name and load the
+     * image in the object
+     *
+     * @param number the pdf object number
+     * @param xnumber the pdf object X number
+     * @param cont the pdf stream contents
+     */
+    public PDFFormXObject(int number, int xnumber, PDFStream cont, String ref) {
+        super(number, xnumber, null);
+        contents = cont;
+        resRef = ref;
+    }
+
+    /**
+     * Output the form stream as PDF.
+     * This sets up the form XObject dictionary and adds the content
+     * data stream.
+     *
+     * @param stream the output stream to write the data
+     * @throws IOException if there is an error writing the data
+     * @return the length of the data written
+     */
+    protected int output(OutputStream stream) throws IOException {
+        int length = 0;
+
+        String dictEntries = contents.applyFilters();
+
+        String p = this.number + " " + this.generation + " obj\n";
+        p = p + "<</Type /XObject\n";
+        p = p + "/Subtype /Form\n";
+        p = p + "/FormType 1\n";
+        p = p + "/BBox [0 0 1000 1000]\n";
+        p = p + "/Matrix [1 0 0 1 0 0]\n";
+        p = p + "/Resources " + resRef + "\n";
+        p = p + "/Length " + (contents.getDataLength() + 1) + "\n";
+
+        p = p + dictEntries;
+        p = p + ">>\n";
+
+        // push the pdf dictionary on the writer
+        byte[] pdfBytes = p.getBytes();
+        stream.write(pdfBytes);
+        length += pdfBytes.length;
+        // push all the image data on the writer
+        // and takes care of length for trailer
+        length += contents.outputStreamData(stream);
+
+        pdfBytes = ("endobj\n").getBytes();
+        stream.write(pdfBytes);
+        length += pdfBytes.length;
+        // let it gc
+        // this object is retained as a reference to inserting
+        // the same image but the image data is no longer needed
+        contents = null;
+        return length;
+    }
+}
+
index 8cef07787d4634e2995b09dfaf2dab2658ba8e90..fa958cce4877bcdf7a565a7a6f601a86603f226a 100644 (file)
@@ -43,6 +43,16 @@ public class PDFPage extends PDFResourceContext {
      */
     protected int pageheight;
 
+    /**
+     * Duration to display page
+     */
+    protected int duration = -1;
+
+    /**
+     * Transition dictionary
+     */
+    protected TransitionDictionary trDictionary = null;
+
     /**
      * create a /Page object
      *
@@ -101,6 +111,11 @@ public class PDFPage extends PDFResourceContext {
         this.parent = parent.referencePDF();
     }
 
+    public void setTransition(int dur, TransitionDictionary tr) {
+        duration = dur;
+        trDictionary = tr;
+    }
+
     /**
      * represent this object as PDF
      *
@@ -119,6 +134,12 @@ public class PDFPage extends PDFResourceContext {
         if (this.annotList != null) {
             sb = sb.append("/Annots " + this.annotList.referencePDF() + "\n");
         }
+        if (this.duration != -1) {
+            sb = sb.append("/Dur " + this.duration + "\n");
+        }
+        if (this.trDictionary != null) {
+            sb = sb.append("/Trans << " + this.trDictionary.getDictionary() + " >>\n");
+        }
 
         sb = sb.append(">>\nendobj\n");
         return sb.toString().getBytes();
index 77039ab88439709e73f935ff64f96422162fdd32..6819cf18749d84d78f03b996a01c20e34c425f82 100644 (file)
@@ -69,6 +69,10 @@ public class PDFResourceContext extends PDFObject {
         this.annotList.addAnnot(annot);
     }
 
+    public PDFAnnotList getAnnotations() {
+        return this.annotList;
+    }
+
     public void addGState(PDFGState gstate) {
         this.resources.addGState(gstate);
     }
index 8741bd519e4bc667662107ad26cc33fd4fc59db0..fa7715d51291424d0e351d0ed5f3dc81c031e9b3 100644 (file)
@@ -24,7 +24,7 @@ public class PDFRoot extends PDFObject {
     /**
      * Root outline object
      */
-    private PDFOutline _outline;
+    private PDFOutline outline;
 
     /**
      * create a Root (/Catalog) object. NOTE: The PDFRoot
@@ -67,15 +67,14 @@ public class PDFRoot extends PDFObject {
         this.rootPages = pages;
     }
 
-    public void setRootOutline(PDFOutline outline) {
-        _outline = outline;
+    public void setRootOutline(PDFOutline out) {
+        outline = out;
     }
 
     public PDFOutline getRootOutline() {
-        return _outline;
+        return outline;
     }
 
-
     /**
      * represent the object as PDF.
      *
@@ -90,10 +89,9 @@ public class PDFRoot extends PDFObject {
                                           + " obj\n<< /Type /Catalog\n/Pages "
                                           + this.rootPages.referencePDF()
                                           + "\n");
-        if (_outline != null) {
-            p.append(" /Outlines " + _outline.referencePDF() + "\n");
+        if (outline != null) {
+            p.append(" /Outlines " + outline.referencePDF() + "\n");
             p.append(" /PageMode /UseOutlines\n");
-
         }
         p.append(" >>\nendobj\n");
         return p.toString().getBytes();
diff --git a/src/org/apache/fop/pdf/TransitionDictionary.java b/src/org/apache/fop/pdf/TransitionDictionary.java
new file mode 100644 (file)
index 0000000..fd55672
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * $Id$
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources.
+ */
+
+package org.apache.fop.pdf;
+
+import java.util.Map;
+import java.util.Iterator;
+
+/**
+ * Transition Dictionary
+ * This class is used to build a transition dictionary to
+ * specify the transition between pages.
+ */
+public class TransitionDictionary extends PDFObject {
+
+    private Map dictionaryValues;
+
+    /**
+     * Create a Transition Dictionary
+     *
+     * @param values the dictionary values to output
+     */
+    public TransitionDictionary(Map values) {
+        dictionaryValues = values;
+    }
+
+    /**
+     * Get the dictionary.
+     * This returns the string containing the dictionary values.
+     */
+    public String getDictionary() {
+        StringBuffer sb = new StringBuffer();
+        for (Iterator iter = dictionaryValues.keySet().iterator(); iter.hasNext();) {
+            Object key = iter.next();
+            sb.append(key + " " + dictionaryValues.get(key) + "\n");
+        }
+        return sb.toString();
+    }
+
+    /**
+     * there is nothing to return for the toPDF method, as it should not be called
+     *
+     * @return an empty string
+     */
+    public byte[] toPDF() {
+        return new byte[0];
+    }
+}
+
index 1fc8d832dba3f6d51c4784c50665ee12b9555bad..609023e1aeca5176e5e140ca15ee1077f56a817c 100644 (file)
@@ -22,7 +22,8 @@ import org.apache.fop.pdf.PDFStream;
 import org.apache.fop.pdf.PDFDocument; 
 import org.apache.fop.pdf.PDFInfo;
 import org.apache.fop.pdf.PDFResources;
-import org.apache.fop.pdf.PDFXObject;      
+import org.apache.fop.pdf.PDFResourceContext;
+import org.apache.fop.pdf.PDFXObject;
 import org.apache.fop.pdf.PDFPage;        
 import org.apache.fop.pdf.PDFState;
 import org.apache.fop.pdf.PDFLink;
@@ -131,7 +132,7 @@ public class PDFRenderer extends PrintRenderer {
     /**
      * the current annotation list to add annotations to
      */
-    protected PDFAnnotList currentAnnotList;
+    protected PDFResourceContext currentContext = null;
 
     /**
      * the current page to add annotations to
@@ -369,16 +370,17 @@ public class PDFRenderer extends PrintRenderer {
         // Transform origin at top left to origin at bottom left
         currentStream.add("1 0 0 -1 0 "
                            + (int) Math.round(pageHeight / 1000) + " cm\n");
-        //currentStream.add("BT\n");
         currentFontName = "";
 
         Page p = page.getPage();
         renderPageAreas(p);
 
-        //currentStream.add("ET\n");
-
         this.pdfDoc.addStream(currentStream);
         currentPage.setContents(currentStream);
+        PDFAnnotList annots = currentPage.getAnnotations();
+        if (annots != null) {
+            this.pdfDoc.addAnnotList(annots);
+        }
         this.pdfDoc.addPage(currentPage);
         this.pdfDoc.output(ostream);
     }
@@ -899,7 +901,7 @@ public class PDFRenderer extends PrintRenderer {
      * Checks to see if we have some text rendering commands open
      * still and writes out the TJ command to the stream if we do
      */
-    private void closeText() {
+    protected void closeText() {
         if (textOpen) {
             currentStream.add("] TJ\n");
             textOpen = false;
@@ -989,14 +991,14 @@ public class PDFRenderer extends PrintRenderer {
                 return;
             }
             FopPDFImage pdfimage = new FopPDFImage(fopimage, url);
-            int xobj = pdfDoc.addImage(null, pdfimage).getXNumber();
+            int xobj = pdfDoc.addImage(currentContext, pdfimage).getXNumber();
             fact.releaseImage(url, userAgent);
         } else if ("image/jpeg".equals(mime)) {
             if (!fopimage.load(FopImage.ORIGINAL_DATA, userAgent)) {
                 return;
             }
             FopPDFImage pdfimage = new FopPDFImage(fopimage, url);
-            int xobj = pdfDoc.addImage(null, pdfimage).getXNumber();
+            int xobj = pdfDoc.addImage(currentContext, pdfimage).getXNumber();
             fact.releaseImage(url, userAgent);
 
             int w = (int) pos.getWidth() / 1000;
@@ -1008,7 +1010,7 @@ public class PDFRenderer extends PrintRenderer {
                 return;
             }
             FopPDFImage pdfimage = new FopPDFImage(fopimage, url);
-            int xobj = pdfDoc.addImage(null, pdfimage).getXNumber();
+            int xobj = pdfDoc.addImage(currentContext, pdfimage).getXNumber();
             fact.releaseImage(url, userAgent);
 
             int w = (int) pos.getWidth() / 1000;
@@ -1049,6 +1051,8 @@ public class PDFRenderer extends PrintRenderer {
         context.setProperty(PDFXMLHandler.OUTPUT_STREAM, ostream);
         context.setProperty(PDFXMLHandler.PDF_STATE, currentState);
         context.setProperty(PDFXMLHandler.PDF_PAGE, currentPage);
+        context.setProperty(PDFXMLHandler.PDF_CONTEXT, currentContext == null ? currentPage: currentContext);
+        context.setProperty(PDFXMLHandler.PDF_CONTEXT, currentContext);
         context.setProperty(PDFXMLHandler.PDF_STREAM, currentStream);
         context.setProperty(PDFXMLHandler.PDF_XPOS,
                             new Integer(currentBlockIPPosition + (int) pos.getX()));
index d111aeb1ff9ce8760a610b041e4e6332e7be7b05..ff0813c46d4f4da3b3089488926fcd5dfe7c75fd 100644 (file)
@@ -14,6 +14,7 @@ import org.apache.fop.pdf.PDFPage;
 import org.apache.fop.pdf.PDFState;
 import org.apache.fop.pdf.PDFStream;
 import org.apache.fop.pdf.PDFNumber;
+import org.apache.fop.pdf.PDFResourceContext;
 import org.apache.fop.svg.PDFTextElementBridge;
 import org.apache.fop.svg.PDFAElementBridge;
 import org.apache.fop.svg.PDFGraphics2D;
@@ -62,6 +63,11 @@ public class PDFXMLHandler implements XMLHandler {
      */
     public static final String PDF_PAGE = "pdfPage";
 
+    /**
+     * The current PDF page for page renference and as a resource context.
+     */
+    public static final String PDF_CONTEXT = "pdfContext";
+
     /**
      * The current PDF stream to draw directly to.
      */
@@ -141,6 +147,7 @@ public class PDFXMLHandler implements XMLHandler {
         pdfi.outputStream = (OutputStream)context.getProperty(OUTPUT_STREAM);
         pdfi.pdfState = (PDFState)context.getProperty(PDF_STATE);
         pdfi.pdfPage = (PDFPage)context.getProperty(PDF_PAGE);
+        pdfi.pdfContext = (PDFResourceContext)context.getProperty(PDF_CONTEXT);
         pdfi.currentStream = (PDFStream)context.getProperty(PDF_STREAM);
         pdfi.width = ((Integer)context.getProperty(PDF_WIDTH)).intValue();
         pdfi.height = ((Integer)context.getProperty(PDF_HEIGHT)).intValue();
@@ -164,6 +171,8 @@ public class PDFXMLHandler implements XMLHandler {
         public PDFState pdfState;
         /** see PDF_PAGE */
         public PDFPage pdfPage;
+        /** see PDF_CONTEXT */
+        public PDFResourceContext pdfContext;
         /** see PDF_STREAM */
         public PDFStream currentStream;
         /** see PDF_WIDTH */
@@ -256,7 +265,7 @@ public class PDFXMLHandler implements XMLHandler {
             }
 
             PDFGraphics2D graphics = new PDFGraphics2D(true, pdfInfo.fi, pdfInfo.pdfDoc,
-                                     pdfInfo.pdfPage, pdfInfo.pdfPage.referencePDF(),
+                                     pdfInfo.pdfContext, pdfInfo.pdfPage.referencePDF(),
                                      pdfInfo.currentFontName,
                                      pdfInfo.currentFontSize);
             graphics.setGraphicContext(new org.apache.batik.ext.awt.g2d.GraphicContext());
index e147f8b90c21efaf60a33c9d51c69b0bfbc93d5d..f31ca91d622b69f5129b3a01b634b1eff5527779 100644 (file)
@@ -14,6 +14,7 @@ import org.apache.fop.pdf.PDFState;
 import org.apache.fop.pdf.PDFNumber;
 import org.apache.fop.pdf.PDFResources;
 import org.apache.fop.pdf.PDFColor;
+import org.apache.fop.pdf.PDFAnnotList;
 import org.apache.fop.render.pdf.FontSetup;
 import org.apache.fop.layout.FontInfo;
 
@@ -179,6 +180,10 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D {
         pdfStream.add(getString());
         this.pdfDoc.addStream(pdfStream);
         currentPage.setContents(pdfStream);
+        PDFAnnotList annots = currentPage.getAnnotations();
+        if (annots != null) {
+            this.pdfDoc.addAnnotList(annots);
+        }
         this.pdfDoc.addPage(currentPage);
         if (fontInfo != null) {
             FontSetup.addToResources(pdfDoc, pdfDoc.getResources(), fontInfo);
index d4b51156f064daf46c2f8fb7451f4798f126f997..8ac1f78bc5c0f00a65c66454c3000ec88a241b88 100644 (file)
@@ -18,6 +18,7 @@ import org.apache.fop.pdf.PDFXObject;
 import org.apache.fop.pdf.PDFPattern;
 import org.apache.fop.pdf.PDFDocument;
 import org.apache.fop.pdf.PDFLink;
+import org.apache.fop.pdf.PDFAnnotList;
 import org.apache.fop.pdf.BitmapImage;
 import org.apache.fop.layout.FontInfo;
 import org.apache.fop.layout.FontState;
@@ -985,6 +986,11 @@ public class PDFGraphics2D extends AbstractGraphics2D {
 
         currentStream.write(myPat.getColorSpaceOut(fill));
 
+        PDFAnnotList annots = context.getAnnotations();
+        if (annots != null) {
+            this.pdfDoc.addAnnotList(annots);
+        }
+
         if (outputStream != null) {
             try {
                 this.pdfDoc.output(outputStream);