]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Fix for internal forward references in PDF output (basic-link with internal-destination):
authorJeremias Maerki <jeremias@apache.org>
Tue, 18 Oct 2005 16:06:31 +0000 (16:06 +0000)
committerJeremias Maerki <jeremias@apache.org>
Tue, 18 Oct 2005 16:06:31 +0000 (16:06 +0000)
Implemented by making out-of-order processing possible. The problem will still surface if supportsOutOfOrder() returns false.
PDF library now supports the addition of pages in non-consecutive order. This is a backwards-compatible change. The old behaviour and the old method signatures are still in place.
PageViewport now carries a page index which doesn't represent the page number but the overall index of the page within the current rendering run.

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

src/java/org/apache/fop/area/AreaTreeModel.java
src/java/org/apache/fop/area/PageViewport.java
src/java/org/apache/fop/pdf/PDFFactory.java
src/java/org/apache/fop/pdf/PDFPage.java
src/java/org/apache/fop/pdf/PDFPages.java
src/java/org/apache/fop/render/pdf/PDFRenderer.java

index 34a4d39fa16e2d96ee813a27ee97943c3c6583a3..75783def85cd94091ae3525f8457fefac2b4e3f1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -38,6 +38,7 @@ import org.apache.commons.logging.LogFactory;
  */
 public class AreaTreeModel {
     private List pageSequenceList = null;
+    private int currentPageSequenceIndex = -1;
     private List currentPageSequencePageList;
     private List offDocumentItems = new java.util.ArrayList();
 
@@ -57,6 +58,7 @@ public class AreaTreeModel {
     public void startPageSequence(LineArea title) {
         currentPageSequencePageList = new java.util.ArrayList();
         pageSequenceList.add(currentPageSequencePageList);
+        currentPageSequenceIndex = pageSequenceList.size() - 1;
     }
 
     /**
@@ -65,6 +67,12 @@ public class AreaTreeModel {
      */
     public void addPage(PageViewport page) {
         currentPageSequencePageList.add(page);
+        int pageIndex = 0;
+        for (int i = 0; i < currentPageSequenceIndex; i++) {
+            pageIndex += ((List)pageSequenceList.get(i)).size();
+        }
+        pageIndex += currentPageSequencePageList.size() - 1;
+        page.setPageIndex(pageIndex);
     }
 
     /**
index 046bd4698b8cde8afe5a82eda2c87dcc20d57c76..2cced4a5f2557d72e837ef24a34568cae50b34ae 100644 (file)
@@ -48,6 +48,7 @@ public class PageViewport implements Resolvable, Cloneable {
     private Rectangle2D viewArea;
     private boolean clip = false;
     private String pageNumberString = null;
+    private int pageIndex = -1; //-1 = undetermined
     private SimplePageMaster spm = null;
     private boolean blank;
 
@@ -137,6 +138,22 @@ public class PageViewport implements Resolvable, Cloneable {
         return pageNumberString;
     }
 
+    /**
+     * Sets the page index of the page in this rendering run.
+     * @param index the page index (zero-based), -1 if it is undetermined
+     */
+    public void setPageIndex(int index) {
+        this.pageIndex = index;
+    }
+    
+    /**
+     * @return the overall page index of the page in this rendering run (zero-based, 
+     *         -1 if it is undetermined).
+     */
+    public int getPageIndex() {
+        return this.pageIndex;
+    }
+    
     /**
      * Get the key for this page viewport.
      * This is used so that a serializable key can be used to
index 28a14e8effae8e3ca87d5c96e2bf236dc001cd5c..bacb3251c1dd41a90b692489931d30771c859160 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -133,26 +133,43 @@ public class PDFFactory {
      * PDFDocument later using addObject().
      *
      * @param resources resources object to use
-     * @param pagewidth width of the page in points
-     * @param pageheight height of the page in points
+     * @param pageWidth width of the page in points
+     * @param pageHeight height of the page in points
+     * @param pageIndex index of the page (zero-based)
      *
      * @return the created /Page object
      */
     public PDFPage makePage(PDFResources resources,
-                            int pagewidth, int pageheight) {
+                            int pageWidth, int pageHeight, int pageIndex) {
 
         /*
          * create a PDFPage with the next object number, the given
          * resources, contents and dimensions
          */
         PDFPage page = new PDFPage(resources,
-                                   pagewidth, pageheight);
+                                   pageWidth, pageHeight, pageIndex);
 
         getDocument().assignObjectNumber(page);
         getDocument().getPages().addPage(page);
         return page;
     }
 
+    /**
+     * Make a /Page object. The page is assigned an object number immediately
+     * so references can already be made. The page must be added to the
+     * PDFDocument later using addObject().
+     *
+     * @param resources resources object to use
+     * @param pageWidth width of the page in points
+     * @param pageHeight height of the page in points
+     *
+     * @return the created /Page object
+     */
+    public PDFPage makePage(PDFResources resources,
+                            int pageWidth, int pageHeight) {
+        return makePage(resources, pageWidth, pageHeight, -1);
+    }
+
     /* ========================= functions ================================= */
 
     /**
index 74932403fba6557632720ddc944b9c8d92c87121..bd00cbd2d8a3b781638bf56126a94798ef39f4fd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -48,6 +48,9 @@ public class PDFPage extends PDFResourceContext {
      */
     protected int pageheight;
 
+    /** the page index (zero-based) */
+    protected int pageIndex;
+    
     /**
      * Duration to display page
      */
@@ -59,41 +62,38 @@ public class PDFPage extends PDFResourceContext {
     protected TransitionDictionary trDictionary = null;
 
     /**
-     * create a /Page object
+     * Create a /Page object
      *
      * @param resources the /Resources object
      * @param contents the content stream
-     * @param pagewidth the page's width in points
-     * @param pageheight the page's height in points
+     * @param pageWidth the page's width in points
+     * @param pageHeight the page's height in points
+     * @param pageIndex the page's zero-based index (or -1 if the page number is auto-determined)
      */
     public PDFPage(PDFResources resources, PDFStream contents,
-                   int pagewidth, int pageheight) {
+                   int pageWidth, int pageHeight, int pageIndex) {
 
         /* generic creation of object */
         super(resources);
 
         /* set fields using parameters */
         this.contents = contents;
-        this.pagewidth = pagewidth;
-        this.pageheight = pageheight;
+        this.pagewidth = pageWidth;
+        this.pageheight = pageHeight;
+        this.pageIndex = pageIndex;
     }
 
     /**
-     * create a /Page object
+     * Create a /Page object
      *
      * @param resources the /Resources object
-     * @param pagewidth the page's width in points
-     * @param pageheight the page's height in points
+     * @param pageWidth the page's width in points
+     * @param pageHeight the page's height in points
+     * @param pageIndex the page's zero-based index (or -1 if the page number is auto-determined)
      */
     public PDFPage(PDFResources resources,
-                   int pagewidth, int pageheight) {
-
-        /* generic creation of object */
-        super(resources);
-
-        /* set fields using parameters */
-        this.pagewidth = pagewidth;
-        this.pageheight = pageheight;
+                   int pageWidth, int pageHeight, int pageIndex) {
+        this(resources, null, pageWidth, pageHeight, pageIndex);
     }
 
     /**
@@ -143,6 +143,14 @@ public class PDFPage extends PDFResourceContext {
         return this.pageheight;
     }
 
+    /**
+     * @return the page Index of this page (zero-based), -1 if it the page index should
+     *         automatically be determined.
+     */
+    public int getPageIndex() {
+        return this.pageIndex;
+    }
+    
     /**
      * @see org.apache.fop.pdf.PDFObject#toPDFString()
      */
index aae5c6c90c9552391207b3b0dc581cccd8057679..6ce4830e1089f5e0da88c0bd99d9df2ab2ba875e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -72,7 +72,19 @@ public class PDFPages extends PDFObject {
      * @param page the child page
      */
     public void notifyKidRegistered(PDFPage page) {
-        this.kids.add(page.referencePDF());
+        int idx = page.getPageIndex();
+        if (idx >= 0) {
+            while (idx > this.kids.size() - 1) {
+                this.kids.add(null);
+            }
+            if (this.kids.get(idx) != null) {
+                throw new IllegalStateException("A page already exists at index " 
+                        + idx + " (zero-based).");
+            }
+            this.kids.set(idx, page.referencePDF());
+        } else {
+            this.kids.add(page.referencePDF());
+        }
     }
 
     /**
@@ -102,7 +114,11 @@ public class PDFPages extends PDFObject {
             append(this.getCount()).
             append("\n/Kids [");
         for (int i = 0; i < kids.size(); i++) {
-            sb.append(kids.get(i)).append(" ");
+            Object kid = kids.get(i);
+            if (kid == null) {
+                throw new IllegalStateException("Gap in the kids list!");
+            }
+            sb.append(kid).append(" ");
         }
         sb.append("] >>\nendobj\n");
         return sb.toString();
index ba8b6796e14bab2bfdc1be1247016eb508e78f70..70beb20fb89d6d0e10a0996c759a751f81e212c9 100644 (file)
@@ -283,7 +283,8 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
      * @see org.apache.fop.render.Renderer#supportsOutOfOrder()
      */
     public boolean supportsOutOfOrder() {
-        return false;
+        //return false;
+        return true;
     }
 
     /**
@@ -402,6 +403,14 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
      * @param page the page to prepare
      */
     public void preparePage(PageViewport page) {
+        setupPage(page);
+        if (pages == null) {
+            pages = new java.util.HashMap();
+        }
+        pages.put(page, currentPage);
+    }
+
+    private void setupPage(PageViewport page) {
         this.pdfResources = this.pdfDoc.getResources();
 
         Rectangle2D bounds = page.getViewArea();
@@ -409,15 +418,12 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
         double h = bounds.getHeight();
         currentPage = this.pdfDoc.getFactory().makePage(
             this.pdfResources,
-            (int) Math.round(w / 1000), (int) Math.round(h / 1000));
-        if (pages == null) {
-            pages = new java.util.HashMap();
-        }
-        pages.put(page, currentPage);
+            (int) Math.round(w / 1000), (int) Math.round(h / 1000),
+            page.getPageIndex());
         pageReferences.put(page.getKey(), currentPage.referencePDF());
         pvReferences.put(page.getKey(), page);
     }
-
+    
     /**
      * This method creates a pdf stream for the current page
      * uses it as the contents of a new page. The page is written
@@ -428,22 +434,15 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
                 throws IOException, FOPException {
         if (pages != null
                 && (currentPage = (PDFPage) pages.get(page)) != null) {
+            //Retrieve previously prepared page (out-of-line rendering)
             pages.remove(page);
-            Rectangle2D bounds = page.getViewArea();
-            double h = bounds.getHeight();
-            pageHeight = (int) h;
         } else {
-            this.pdfResources = this.pdfDoc.getResources();
-            Rectangle2D bounds = page.getViewArea();
-            double w = bounds.getWidth();
-            double h = bounds.getHeight();
-            pageHeight = (int) h;
-            currentPage = this.pdfDoc.getFactory().makePage(
-                this.pdfResources,
-                (int) Math.round(w / 1000), (int) Math.round(h / 1000));
-            pageReferences.put(page.getKey(), currentPage.referencePDF());
-            pvReferences.put(page.getKey(), page);
+            setupPage(page);
         }
+        Rectangle2D bounds = page.getViewArea();
+        double h = bounds.getHeight();
+        pageHeight = (int) h;
+
         currentStream = this.pdfDoc.getFactory()
             .makeStream(PDFFilterList.CONTENT_FILTER, false);