You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2009/09/01 18:42:12 UTC

svn commit: r810114 - in /incubator/pdfbox/trunk/src/main/java/org/apache/pdfbox/pdmodel: PDDocument.java common/COSArrayList.java

Author: lehmi
Date: Tue Sep  1 16:42:12 2009
New Revision: 810114

URL: http://svn.apache.org/viewvc?rev=810114&view=rev
Log:
PDFBOX-493: adding the ability to get page number for bookmarks. Patch from Adam Nichols (adam at swmc dot com)

Modified:
    incubator/pdfbox/trunk/src/main/java/org/apache/pdfbox/pdmodel/PDDocument.java
    incubator/pdfbox/trunk/src/main/java/org/apache/pdfbox/pdmodel/common/COSArrayList.java

Modified: incubator/pdfbox/trunk/src/main/java/org/apache/pdfbox/pdmodel/PDDocument.java
URL: http://svn.apache.org/viewvc/incubator/pdfbox/trunk/src/main/java/org/apache/pdfbox/pdmodel/PDDocument.java?rev=810114&r1=810113&r2=810114&view=diff
==============================================================================
--- incubator/pdfbox/trunk/src/main/java/org/apache/pdfbox/pdmodel/PDDocument.java (original)
+++ incubator/pdfbox/trunk/src/main/java/org/apache/pdfbox/pdmodel/PDDocument.java Tue Sep  1 16:42:12 2009
@@ -31,12 +31,16 @@
 import java.io.OutputStream;
 import java.net.URL;
 import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.cos.COSBase;
 import org.apache.pdfbox.cos.COSDictionary;
 import org.apache.pdfbox.cos.COSDocument;
 import org.apache.pdfbox.cos.COSInteger;
 import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSObject;
 import org.apache.pdfbox.cos.COSStream;
 import org.apache.pdfbox.exceptions.COSVisitorException;
 import org.apache.pdfbox.exceptions.CryptographyException;
@@ -44,6 +48,7 @@
 import org.apache.pdfbox.io.RandomAccess;
 import org.apache.pdfbox.pdfparser.PDFParser;
 import org.apache.pdfbox.pdfwriter.COSWriter;
+import org.apache.pdfbox.pdmodel.common.COSArrayList;
 import org.apache.pdfbox.pdmodel.common.PDRectangle;
 import org.apache.pdfbox.pdmodel.common.PDStream;
 import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
@@ -99,6 +104,13 @@
 
 
     /**
+     * This assocates object ids with a page number.  It's used to determine
+     * the page number for bookmarks (or page numbers for anything else for
+     * which you have an object id for that matter). 
+     */
+    private Map pageMap = null;
+
+    /**
      * Constructor, creates a new PDF Document with no pages.  You need to add
      * at least one page for the document to be valid.
      *
@@ -127,6 +139,96 @@
         pages.setItem( COSName.COUNT, new COSInteger( 0 ) );
     }
 
+    private void generatePageMap() 
+    {
+        pageMap = new HashMap();
+        // these page nodes could be references to pages, 
+        // or references to arrays which have references to pages
+        // or references to arrays which have references to arrays which have references to pages
+        // or ... (I think you get the idea...)
+        COSArray pageNodes = ((COSArrayList)(getDocumentCatalog().getPages().getKids())).toList();
+        
+        for(int arrayCounter=0; arrayCounter < pageNodes.size(); ++arrayCounter) 
+        {
+            parseCatalogObject((COSObject)pageNodes.get(arrayCounter));
+        }
+    }
+             
+    /**
+     * This will either add the page passed in, or, if it's a pointer to an array
+     * of pages, it'll recursivly call itself and process everything in the list.
+     */
+    private void parseCatalogObject(COSObject thePageOrArrayObject) 
+    {
+        COSBase arrayCountBase = thePageOrArrayObject.getItem(COSName.COUNT);
+        int arrayCount = -1;
+        if(arrayCountBase instanceof COSInteger)
+        {
+            arrayCount = ((COSInteger)arrayCountBase).intValue();
+        }
+ 
+        COSBase kidsBase = thePageOrArrayObject.getItem(COSName.KIDS);
+        int kidsCount = -1;
+        if(kidsBase instanceof COSArray)
+        {
+            kidsCount = ((COSArray)kidsBase).size();
+        }
+     
+        if(arrayCount == -1 || kidsCount == -1) 
+        {
+            // these cases occur when we have a page, not an array of pages
+            String objStr = String.valueOf(thePageOrArrayObject.getObjectNumber().intValue());
+            String genStr = String.valueOf(thePageOrArrayObject.getGenerationNumber().intValue());
+            getPageMap().put(objStr+","+genStr, new Integer(getPageMap().size()+1));
+        } 
+        else 
+        {
+            // we either have an array of page pointers, or an array of arrays
+            if(arrayCount == kidsCount) 
+            {
+                // process the kids... they're all references to pages
+                COSArray kidsArray = ((COSArray)kidsBase);
+                for(int i=0; i<kidsArray.size(); ++i) 
+                {
+                    COSObject thisObject = (COSObject)kidsArray.get(i);
+                    String objStr = String.valueOf(thisObject.getObjectNumber().intValue());
+                    String genStr = String.valueOf(thisObject.getGenerationNumber().intValue());
+                    getPageMap().put(objStr+","+genStr, new Integer(getPageMap().size()+1));
+                }
+            } 
+            else 
+            {
+                // this object is an array of references to other arrays
+                COSArray list = null;
+                if(kidsBase instanceof COSArray)
+                {
+                    list = ((COSArray)kidsBase);
+                }
+                if(list != null) 
+                {
+                    for(int arrayCounter=0; arrayCounter < list.size(); ++arrayCounter) 
+                    {
+                        parseCatalogObject((COSObject)list.get(arrayCounter));
+                    }
+                }
+            }
+        }
+    }
+ 
+    /**
+     * This will return the Map containing the mapping from object-ids to pagenumbers.
+     * 
+     * @return the pageMap
+     */
+    public final Map getPageMap() 
+    {
+        if (pageMap != null)
+        {
+            generatePageMap();
+        }
+        return pageMap;
+    }
+
     /**
      * This will add a page to the document.  This is a convenience method, that
      * will add the page to the root of the hierarchy and set the parent of the

Modified: incubator/pdfbox/trunk/src/main/java/org/apache/pdfbox/pdmodel/common/COSArrayList.java
URL: http://svn.apache.org/viewvc/incubator/pdfbox/trunk/src/main/java/org/apache/pdfbox/pdmodel/common/COSArrayList.java?rev=810114&r1=810113&r2=810114&view=diff
==============================================================================
--- incubator/pdfbox/trunk/src/main/java/org/apache/pdfbox/pdmodel/common/COSArrayList.java (original)
+++ incubator/pdfbox/trunk/src/main/java/org/apache/pdfbox/pdmodel/common/COSArrayList.java Tue Sep  1 16:42:12 2009
@@ -651,4 +651,15 @@
     {
         return "COSArrayList{" + array.toString() + "}";
     }
+    
+    /**
+     * This will return then underlying COSArray.
+     * 
+     * @return the COSArray
+     */
+    public COSArray toList() 
+    {
+        return array;
+    }
+
 }