You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@pdfbox.apache.org by Kevin Brown <kb...@gmail.com> on 2010/06/30 17:03:40 UTC

Re: getting and setting names of named destinations

Ok, sort of pigybacking off the previous discussions... I was able to get
PDFBox to allow me to get the page numbers of named dests, and even to alter
the zoom factor for each one. However, I cannot get and/or set the names
themselves (the actual names of the named destinations). Anyone got any
ideas? Would this be something that could be added into a future release?

Thanks,

Kevin


On Sun, Jun 20, 2010 at 1:13 AM, Hesham G. <he...@gmail.com> wrote:

> Thank you Adam for the explanation, and thanks Kevin for the code.
> As Adam says it's high level of precision ... But Kevin did a nice work
> here.
>
> Best regards ,
> Hesham
>
>
> ---------------------------------------------
> Included message :
>
>
> > One thing I haven't been able to get is the actual name of the named
> > destinations. You would think there would be something like getName()
> > setName() methods. I'll keep poking around.
> >
> >
> > On Fri, Jun 18, 2010 at 1:23 PM, Kevin Brown <kb...@gmail.com> wrote:
> >
> >> This aint pretty. It's just a proof of concept written by a Java hacking
> >> fool. I'm going to refactor if I get approval. :)
> >>
> >> Basically you need to start with this (document is a PDDocument):
> >>
> >>
> >>     PDDocumentCatalog log = document.getDocumentCatalog();
> >>
> >>         PDDocumentNameDictionary dic = log.getNames();
> >>         PDDestinationNameTreeNode dests = dic.getDests();
> >>
> >> Okay, so the destinations will be available via the getNames() method of
> >> dests, if they exist at that level. If they do not, you need to bore
> down by
> >> using the getKids() method, and check those items for names. If those
> don't
> >> work, bore down, etc. Here I print out all the named destinations, and
> >> change the zoom property, for a particular type of  PDF; you may need to
> >> land at a different level of PDDestinationNameTreeNode.
> >>
> >> The PDPageXYZDestination class is the thing to keep an eye on.
> >>
> >>     private static boolean hasDests(PDDestinationNameTreeNode dests)
> throws
> >> IOException {
> >>         if (dests.getNames() == null) {
> >>             List kids = dests.getKids();
> >>             List<PDNameTreeNode> destList = kids;
> >>             System.out.println("No. of kids: " + destList.size());
> >>             boolean val = false;
> >>             for (PDNameTreeNode dest2 : destList) {
> >>                 System.out.println("in for");
> >>                 Map<?, ?> destList2 = dest2.getNames();
> >>                 // System.out.println("getnames... " +
> dest2.getNames());
> >>
> >>                 if (destList2 != null) {
> >>                     System.out.println("we have some dests now...");
> >>
> >>                     Collection<PDPageXYZDestination> values =
> >> (Collection<PDPageXYZDestination>) destList2.values();
> >>                     Collection<PDPageXYZDestination> c = values;
> >>                     System.out.println(c.size());
> >>                     for (PDPageXYZDestination destNode : c) {
> >>                         System.out.println(destNode.toString());
> >>
> >>                         System.out.println("tostring: " +
> >> destNode.toString());
> >>                         System.out.println("getleft: " +
> >> destNode.getLeft());
> >>                         System.out.println("getpagenumber" +
> >> destNode.getPageNumber());
> >>                         System.out.println("gettop: " +
> destNode.getTop());
> >>                         System.out.println("getzoom: " +
> >> destNode.getZoom());
> >>                         System.out.println("getpagenumber: " +
> >> destNode.getPage());
> >>                         System.out.println("getcosarray: " +
> >> destNode.getCOSArray());
> >>                         System.out.println("find page number: " +
> >> destNode.findPageNumber());
> >>                         System.out.println("getcosobject: " +
> >> destNode.getCOSObject());
> >>
> >>
> >> System.out.println("********************************************");
> >>                         destNode.setZoom(-1);
> >>                         val = true;
> >>                     }
> >>
> >>                     System.out.println("next in for...");
> >>                 } else {
> >>
> >>                     System.out.println("no names!");
> >>                 }
> >>
> >>             }
> >>             System.out.println("returning ... " + val);
> >>             return val;
> >>         } else {
> >>             System.out.println("returning false...");
> >>             return false;
> >>
> >>         }
> >>     }
> >>
> >>
> >> On Fri, Jun 18, 2010 at 12:09 PM, <Ad...@swmc.com> wrote:
> >>
> >>> Hesham,
> >>>        A named destination is a specific type of node in the document
> >>> outline (aka a specific type of bookmark).  A "normal" bookmark will
> point
> >>> to a page (via the page's object ID and revision) while a named
> >>> destination will point to some name.  Then that needs to be resolved
> >>> (somehow?) to the specific object that it points to.  The object could
> be
> >>> a page, an image, a paragraph, word, or anything else you'll find in a
> >>> PDF.  The main difference is that you can jump to specific point in a
> page
> >>> (e.g. page 3 halfway down where a specific paragraph begins) instead of
> >>> just pointing to the page.  I've never needed this level of precision
> and
> >>> references to pages are simpler and more common (and slightly more
> >>> efficient since it points directly to a page instead of pointing to a
> >>> pointer to an object), so I have not yet used named destinations.  I
> hope
> >>> this helps explain the differences and why one would be chosen over the
> >>> other.
> >>>
> >>> Kevin,
> >>> I too am interested in how you did this, as I expect I'll have to cross
> >>> this bridge at some point.
> >>>
> >>> ----
> >>> Thanks,
> >>> Adam
> >>>
> >>>
> >>>
> >>>
> >>>
> >>> From:
> >>> "Hesham G." <he...@gmail.com>
> >>> To:
> >>> <us...@pdfbox.apache.org>
> >>> Date:
> >>> 06/17/2010 20:14
> >>> Subject:
> >>> Re: getting page numbers of named destinations
> >>>
> >>>
> >>>
> >>> Kevin ,
> >>>
> >>> I have been watching this post out, and I don't seem to understand yet
> >>> what is the difference between "Named destinations" and "bookmarks"  ?
> >>> And I hope if you could share your code with us for how you have got
> it.
> >>>
> >>>
> >>> Best regards ,
> >>> Hesham
> >>>
> >>>
> >>> ---------------------------------------------
> >>> Included message :
> >>>
> >>> > Thank you SO MUCH, Adam. With your advice, and some tinkering with
> >>> PDFBox, I
> >>> > was able to get at and manipulate the named destinations.
> >>> >
> >>> > On Tue, Jun 1, 2010 at 3:23 PM, <Ad...@swmc.com> wrote:
> >>> >
> >>> >> Kevin,
> >>> >>
> >>> >> Section 7.7.2 of the PDF Spec (I'm referencing version 1.7) goes
> over
> >>> the
> >>> >> Document catalog and table 20 points you to section 12.3.2.3 for
> "Named
> >>> >> Destinations").  Section 12.3.2.3 explains that "the correspondence
> >>> >> between name objects and destinations shall be defined by the Dests
> >>> entry
> >>> >> in the document catalogue (see 7.7.2, "Document Catalog")."  So, per
> >>> the
> >>> >> spec, the answer lies in the document catalog.
> >>> >>
> >>> >> Table 28 defines what entries are allowed in the catalog dictionary.
> >>> The
> >>> >> "Document Outline" (i.e. key: "Outlines"), which are also known as
> >>> >> bookmarks, are what you are looping through in your code.  So that's
> >>> why
> >>> >> you're getting bookmarks and not named destinations.  You don't want
> >>> >> document.getDocumentCatalog().getDocumentOutline() but you do want
> >>> >> document.getDocumentCatalog().
> >>> >>
> >>> >> Like I said before, I haven't actually dealt with named
> destinations,
> >>> nor
> >>> >> have I even seen a document which uses them, so I don't know how the
> >>> >> "Dests" key works.  However, it should be pretty easy to figure if
> you
> >>> >> take a look at a PDF in vi, Notepad++, or any other quality editor.
> >>> Once
> >>> >> you know what you're looking for, it's just a matter of looking at
> >>> things
> >>> >> in PDDocumentCatalog to find it.
> >>> >>
> >>> >> ----
> >>> >> Thanks,
> >>> >> Adam
> >>> >>
> >>> >>
> >>> >>
> >>> >>
> >>> >>
> >>> >> From:
> >>> >> Kevin Brown <kb...@gmail.com>
> >>> >> To:
> >>> >> users@pdfbox.apache.org
> >>> >> Date:
> >>> >> 05/25/2010 11:11
> >>> >> Subject:
> >>> >> Re: getting page numbers of named destinations
> >>> >>
> >>> >>
> >>> >>
> >>> >> Thanks much! I'm trying this but it seems to pull in bookmarks, not
> >>> named
> >>> >> destinations. Am I missing something?
> >>> >>
> >>> >>
> >>> >> On Sat, May 22, 2010 at 11:15 AM, Andreas Lehmkuehler
> >>> >> <an...@lehmi.de>wrote:
> >>> >>
> >>> >> > Hi
> >>> >> >
> >>> >> > Kevin Brown schrieb:
> >>> >> >
> >>> >> >  I can't seem to get this done with pdfbox. There doesn't seem to
> be
> >>> a
> >>> >> way
> >>> >> >> to
> >>> >> >> get the page number from the context of the named destination. Am
> I
> >>> >> wrong?
> >>> >> >> Anyone got any sample code for working with named destinations?
> >>> >> >>
> >>> >> > If you have a look at the mentioned example you find some code
> like
> >>> >> this:
> >>> >> >
> >>> >> > PDDocumentOutline
> >>> >> > bookmarks=document.getDocumentCatalog().getDocumentOutline();
> >>> >> > PDOutlineItem item = bookmarks.getFirstChild().getNextSibling();
> >>> >> >
> >>> >> > And the PDOutlineItem class provides a method to get the
> >>> corresponding
> >>> >> > page:
> >>> >> >
> >>> >> > /**
> >>> >> >  * This method will attempt to find the page in this PDF document
> >>> that
> >>> >> this
> >>> >> > outline points to.
> >>> >> >  * If the outline does not point to anything then this method will
> >>> >> return
> >>> >> > null.  If the outline
> >>> >> >  * is an action that is not a GoTo action then this methods will
> >>> throw
> >>> >> the
> >>> >> > OutlineNotLocationException
> >>> >> >  *
> >>> >> >  * @param doc The document to get the page from.
> >>> >> >  *
> >>> >> >  * @return The page that this outline will go to when activated or
> >>> null
> >>> >> if
> >>> >> > it does not point to anything.
> >>> >> >  * @throws IOException If there is an error when trying to find
> the
> >>> >> page.
> >>> >> >  */
> >>> >> > public PDPage findDestinationPage( PDDocument doc ) throws
> >>> IOException
> >>> >> >
> >>> >> > I didn't test it, but theoretically it looks like the piece of
> code
> >>> you
> >>> >> are
> >>> >> > looking for.
> >>> >> >
> >>> >> > BR
> >>> >> > Andreas Lehmkühler
> >>> >> >
> >>> >> >
> >>> >> >
> >>> >> >> On Wed, May 19, 2010 at 12:45 PM, Kevin Brown <kb...@gmail.com>
> >>> wrote:
> >>> >> >>
> >>> >> >>  Thanks. I do need to do that!
> >>> >> >>>
> >>> >> >>> At the moment I'm trying to see if I can get the
> >>> >> >>> GotoSecondBookmarkOnOpen.java sample has any clues... if
> >>> PDOutlineItem
> >>> >> >>> could refer to a named destination then I may be in business!
> >>> >> >>>
> >>> >> >>>
> >>> >> >>>
> >>> >> >>> On Wed, May 19, 2010 at 11:57 AM, <Ad...@swmc.com> wrote:
> >>> >> >>>
> >>> >> >>>  I haven't dealt with named destinations, but if you get get the
> >>> >> object
> >>> >> >>>> ID
> >>> >> >>>> of the page, you can look up the page number with
> >>> doc.getPageMap().
> >>> >> If
> >>> >> >>>> you haven't already, I'd suggest tracing through a PDF with a
> hex
> >>> >> editor
> >>> >> >>>> (or any good quality text editor will work fine) to find out
> how
> >>> >> >>>> everything is connected.
> >>> >> >>>>
> >>> >> >>>> ----
> >>> >> >>>> Thanks,
> >>> >> >>>> Adam
> >>> >> >>>>
> >>> >> >>>>
> >>> >> >>>>
> >>> >> >>>>
> >>> >> >>>>
> >>> >> >>>> From:
> >>> >> >>>> Kevin Brown <kb...@gmail.com>
> >>> >> >>>> To:
> >>> >> >>>> users@pdfbox.apache.org
> >>> >> >>>> Date:
> >>> >> >>>> 05/19/2010 08:42
> >>> >> >>>> Subject:
> >>> >> >>>> getting page numbers of named destinations
> >>> >> >>>>
> >>> >> >>>>
> >>> >> >>>>
> >>> >> >>>> Is it possible to, for a PDF, get the named destinations in it,
> >>> and
> >>> >> find
> >>> >> >>>> out
> >>> >> >>>> what page each is on? It doesn't look like it from my perusal
> of
> >>> the
> >>> >> >>>> documentation, but I'm not sure. Seems like you can get the
> >>> >> destination
> >>> >> >>>> names but that's about it.
> >>> >> >>>>
> >>> >> >>>>
> >>> >> >>>>
> >>> >> >>>> ?  Click here to submit conditions
> >>> >> >>>>
> >>> >> >>>> This email and any content within or attached hereto from  Sun
> >>> West
> >>> >> >>>> Mortgage Company, Inc.  is confidential and/or legally
> privileged.
> >>> >> The
> >>> >> >>>> information is intended only for the use of the individual or
> >>> entity
> >>> >> >>>> named
> >>> >> >>>> on this email. If you are not the intended recipient, you are
> >>> hereby
> >>> >> >>>> notified that any disclosure, copying, distribution or the
> taking
> >>> of
> >>> >> any
> >>> >> >>>> action in reliance on the contents of this email information is
> >>> >> strictly
> >>> >> >>>> prohibited, and that the documents should be returned to this
> >>> office
> >>> >> >>>> immediately by email. Receipt by anyone other than the intended
> >>> >> >>>> recipient is
> >>> >> >>>> not a waiver of any privilege. Please do not include your
> social
> >>> >> >>>> security
> >>> >> >>>> number, account number, or any other personal or financial
> >>> >> information
> >>> >> >>>> in
> >>> >> >>>> the content of the email. Should you have any questions, please
> >>> call
> >>> >> >>>>  (800)
> >>> >> >>>> 453 7884.
> >>> >> >>>>
> >>> >> >>>
> >>> >> >>>
> >>> >> >>>
> >>> >> >>
> >>> >> >
> >>> >>
> >>> >>
> >>> >>
> >>> >> ?  Click here to submit conditions
> >>> >>
> >>> >> This email and any content within or attached hereto from  Sun West
> >>> >> Mortgage Company, Inc.  is confidential and/or legally privileged.
> The
> >>> >> information is intended only for the use of the individual or entity
> >>> named
> >>> >> on this email. If you are not the intended recipient, you are hereby
> >>> >> notified that any disclosure, copying, distribution or the taking of
> >>> any
> >>> >> action in reliance on the contents of this email information is
> >>> strictly
> >>> >> prohibited, and that the documents should be returned to this office
> >>> >> immediately by email. Receipt by anyone other than the intended
> >>> recipient is
> >>> >> not a waiver of any privilege. Please do not include your social
> >>> security
> >>> >> number, account number, or any other personal or financial
> information
> >>> in
> >>> >> the content of the email. Should you have any questions, please call
> >>> (800)
> >>> >> 453 7884.
> >>> >>
> >>> >
> >>>
> >>>
> >>> ?  Click here to submit conditions
> >>>
> >>> This email and any content within or attached hereto from  Sun West
> >>> Mortgage Company, Inc.  is confidential and/or legally privileged. The
> >>> information is intended only for the use of the individual or entity
> named
> >>> on this email. If you are not the intended recipient, you are hereby
> >>> notified that any disclosure, copying, distribution or the taking of
> any
> >>> action in reliance on the contents of this email information is
> strictly
> >>> prohibited, and that the documents should be returned to this office
> >>> immediately by email. Receipt by anyone other than the intended
> recipient is
> >>> not a waiver of any privilege. Please do not include your social
> security
> >>> number, account number, or any other personal or financial information
> in
> >>> the content of the email. Should you have any questions, please call
>  (800)
> >>> 453 7884.
> >>>
> >>
> >>
> >
>

Re: getting and setting names of named destinations

Posted by Ad...@swmc.com.
Did you look at the PDF in a text editor?  Check the object IDs and cross 
reference them with the /Pages from the catalog in both the input file as 
well as the output file.  Once you see how these are lining up, you should 
be able to figure out what the code is doing.  Also, I'd start by just 
removing one page from a small document (perhaps three pages total) to 
keep things simple and easy to work with.

---- 
Thanks,
Adam



From:
"Hesham G." <he...@gmail.com>
To:
<us...@pdfbox.apache.org>
Date:
09/14/2010 01:55
Subject:
Re: getting and setting names of named destinations



Adam ,

I agree with you that this is the logical thing.
But still ... After I copied the PDF with all its bookmarks, then I 
removed some pages, the bookmarks refer to the right location in the page, 
but to wrong pages.
Here is my code, you can try it on the PDF you have downloaded :

String inputpath = "C:\\inputPDF.pdf"; // Has bookmarks with named 
destinations.
String ouputpath = "C:\\outputPDF.pdf";
PDDocument inputPDFFile = PDDocument.load( inputpath );
PDDocument outputPDFFile = new PDDocument(); 
List<PDPage> inputPDFPages = 
inputPDFFile.getDocumentCatalog().getAllPages(); // Get all pages of this 
PDF.


// Copy/Paste all PDF pages :
for( PDPage page: inputPDFPages )
 outputPDFFile.importPage( page );

// Copy/Paste all Named destinations :
PDDocumentCatalog destCatalog = outputPDFFile.getDocumentCatalog();
PDDocumentCatalog srcCatalog = inputPDFFile.getDocumentCatalog();
COSName names = COSName.getPDFName( "Names" );
PDDocumentNameDictionary destNames = destCatalog.getNames();
PDDocumentNameDictionary srcNames = srcCatalog.getNames();

if( srcNames != null ) {
 if( destNames == null )
  destCatalog.getCOSDictionary().setItem(names, 
cloneForNewDocument(outputPDFFile, srcNames));
else
 
destNames.getCOSDictionary().mergeInto((COSDictionary)cloneForNewDocument(outputPDFFile, 
srcNames));
}


// Copy/Paste all bookmarks :
PDDocumentOutline destOutline = destCatalog.getDocumentOutline();
PDDocumentOutline srcOutline = srcCatalog.getDocumentOutline();
if (srcOutline != null) {
 if (destOutline == null) {
  PDDocumentOutline cloned = new 
PDDocumentOutline((COSDictionary)cloneForNewDocument(outputPDFFile, 
srcOutline));
  destCatalog.setDocumentOutline(cloned);
 } else {
  PDOutlineItem first = srcOutline.getFirstChild();
  PDOutlineItem clonedFirst = new 
PDOutlineItem((COSDictionary)cloneForNewDocument( outputPDFFile, first));
  destOutline.appendChild(clonedFirst);
 }
}

// Remove some pages :
outputPDFFile.removePage( 25 ); 
outputPDFFile.removePage( 24 ); 
outputPDFFile.removePage( 23 ); 
outputPDFFile.removePage( 22 ); 
outputPDFFile.removePage( 21 ); 
outputPDFFile.removePage( 20 ); 

outputPDFFile.save( ouputpath );
outputPDFFile.close();



Best regards ,
Hesham

---------------------------------------------
Included message :

getting and setting names of named destinations

> "So if I want to remove a page from the PDF, all Named destinations must 

> be updated manually to refer to the new pages numbers..."
> 
> Not true.  The references are to not page numbers, but the actual object 

> IDs.  When you delete a page, it just drops out of the list of pages 
(and 
> may or may not delete the actual page object, depending on what software 

> you are using).  So the other pages don't change object ID nor revision 
> number.
> 
> ---- 
> Thanks,
> Adam
> 
> 
> 
> 
> 
> From:
> "Hesham G." <he...@gmail.com>
> To:
> <us...@pdfbox.apache.org>
> Date:
> 09/11/2010 02:20
> Subject:
> Re: getting and setting names of named destinations
> 
> 
> 
> Adam ,
> 
> Thanks a lot for the investigation, and for putting me on the right way. 
I 
> have copied the code that copies the Named destinations from the 
> 'PDFMergerUtility' code, and it worked fine. Here is my final code if 
any 
> body needs it :
> I have only 1 problem ... As I understand the Named destinations written 

> at the PDF trailer contains the ND, and the page it refers to, right ?
> So if I want to remove a page from the PDF, all Named destinations must 
be 
> updated manually to refer to the new pages numbers ... But how can I 
> update a bookmark page number, while keeping the Named destination as it 

> is ?
> 
> String inputpath = "C:\\inputPDF.pdf"; // Has bookmarks with named 
> destinations.
> 
> String ouputpath = "C:\\outputPDF.pdf";
> 
> PDDocument inputPDFFile = PDDocument.load( inputpath );
> 
> PDDocument outputPDFFile = new PDDocument(); 
> 
> List<PDPage> inputPDFPages = 
> inputPDFFile.getDocumentCatalog().getAllPages(); // Get all pages of 
this 
> PDF.
> 
> 
> // Copy/Paste all PDF pages :
> 
> for( PDPage page: inputPDFPages )
> 
> outputPDFFile.importPage( page );
> 
> 
> 
> // Copy/Paste all bookmarks(The old code) :
> 
> //PDDocumentOutline pdfBookmarks = 
> inputPDFFile.getDocumentCatalog().getDocumentOutline(); // The bookmarks 

> root object. 
> 
> //outputPDFFile.getDocumentCatalog().setDocumentOutline( pdfBookmarks );
> 
> 
> // Copy/Paste all Named destinations :
> 
> PDDocumentCatalog destCatalog = outputPDFFile.getDocumentCatalog();
> 
> PDDocumentCatalog srcCatalog = inputPDFFile.getDocumentCatalog();
> 
> 
> COSName names = COSName.getPDFName( "Names" );
> 
> PDDocumentNameDictionary destNames = destCatalog.getNames();
> 
> PDDocumentNameDictionary srcNames = srcCatalog.getNames();
> 
> if( srcNames != null ) {
> 
> if( destNames == null )
> 
> destCatalog.getCOSDictionary().setItem(names, 
> cloneForNewDocument(outputPDFFile, srcNames));
> 
> else
> 
> destNames.getCOSDictionary().mergeInto((COSDictionary) 
> cloneForNewDocument(outputPDFFile, srcNames));
> 
> }
> 
> 
> // Copy/Paste all bookmarks :
> 
> PDDocumentOutline destOutline = destCatalog.getDocumentOutline();
> 
> PDDocumentOutline srcOutline = srcCatalog.getDocumentOutline();
> 
> if (srcOutline != null) {
> 
> if (destOutline == null) {
> 
> PDDocumentOutline cloned = new PDDocumentOutline((COSDictionary) 
> cloneForNewDocument(outputPDFFile, srcOutline));
> 
> destCatalog.setDocumentOutline(cloned);
> 
> } else {
> 
> PDOutlineItem first = srcOutline.getFirstChild();
> 
> PDOutlineItem clonedFirst = new PDOutlineItem((COSDictionary) 
> cloneForNewDocument( outputPDFFile, first));
> 
> destOutline.appendChild(clonedFirst);
> 
> }
> 
> }
> 
> 
> //outputPDFFile.removePage( 21 ); // If we used this line it will cause 
> problems to the Named destinations.
> 
> 
> outputPDFFile.save( ouputpath );
> 
> outputPDFFile.close();
> 
> 
> 
> 
> Best regards ,
> Hesham 
> 
> 
> ---------------------------------------------
> Included message :
> 
>> Hesham,
>> 
>> Okay, I was now able to duplicate your findings.  Let's start with the 
>> input file and see how that's laid out.  We'll start with the trailer 
> and 
>> proceed from there:
>> 
>> trailer
>> <</Size 20655/Root 19148 0 R/Info 19146 0 
>> 
> 
R/ID[<ECD3B98C93AEB248888E61674A31F8CF><6362876D55F64E4FAE2312BC1294000B>]/Prev 

> 
>> 116 >>
>> 
>> % next we go to the root node
>> 19148 0 obj<</Names 19164 0 R/Outlines 5147 0 R/Metadata 19145 0 
>> R/AcroForm 19163 0 R/Pages 18985 0 R/Threads 19149 0 R/StructTreeRoot 
> 6272 
>> 0 R/Type/Catalog>>
>> endobj
>> 
>> % Note that 19148 0 appears multiple times, so we're dealing with a 
>> non-conforming PDF
>> % we move on to the Names object
>> 19164 0 obj<</Dests 7710 0 R>>
>> endobj
>> 
>> % then to Dests
>> 7710 0 obj<</Kids[7711 0 R 7712 0 R 7713 0 R 7714 0 R 7715 0 R 7716 0 
> R]>>
>> endobj
>> 
>> % we should go through all of these, but since I already found our 
> target 
>> bookmark ("Classes"), I'll skip straight to 7715 0
>> 7715 0 obj<</Limits[(G1061706)(I1.1011635)]/Kids[10024 0 R 10025 0 R 
> 10026 
>> 0 R 10027 0 R 10028 0 R 10029 0 R 10030 0 R 10031 0 R 10032 0 R 10033 0 

> R 
>> 10034 0 R 10035 0 R 10036 0 R 10037 0 R 10038 0 R 10039 0 R 10040 0 R 
>> 10041 0 R 10042 0 R 10043 0 R 10044 0 R 10045 0 R 10046 0 R 10047 0 R 
>> 10048 0 R 10049 0 R 10050 0 R 10051 0 R 10052 0 R 10053 0 R 10054 0 R 
>> 10055 0 R 10056 0 R 10057 0 R 10058 0 R 10059 0 R 10060 0 R 10061 0 R 
>> 10062 0 R 10063 0 R 10064 0 R 10065 0 R 10066 0 R 10067 0 R 10068 0 R 
>> 10069 0 R 10070 0 R 10071 0 R 10072 0 R 10073 0 R 10074 0 R 10075 0 
R]>>
>> endobj
>> 
>> % again, normally we'd have to go through each of these, but since I 
> know 
>> where it's at, we'll skip right to 10041 0 (I cheated and found the 
>> bookmark and then worked backward to get to the document root)
>> 10041 0 obj<</Limits[(G976459.002)(G976560)]/Names[(G976459.002)11514 0 

>> R(G976459.003)11515 0 R(G976459.004)11516 0 R(G976459.005)11517 0 
>> R(G976460)11518 0 R(G976460.004)11519 0 R(G976461)11520 0 
>> R(G976461.000)11521 0 R(G976461.001)11522 0 R(G976462)11523 0 
>> R(G976462.000)11524 0 R(G976462.001)11525 0 R(G976462.002)11526 0 
>> R(G976462.003)11527 0 R(G976462.004)11528 0 R(G976462.005)11529 0 
>> R(G976463)11530 0 R(G976463.001)11531 0 R(G976463.002)11532 0 
>> R(G976463.003)11533 0 R(G976463.004)11534 0 R(G976463.005)11535 0 
>> R(G976463.006)11536 0 R(G976463.007)11537 0 R(G976463.008)11538 0 
>> R(G976478)11539 0 R(G976491)11540 0 R(G976502)11541 0 R(G976503)11542 0 

>> R(G976504)11543 0 R(G976511)11544 0 R(G976517)11545 0 R(G976518)11546 0 

>> R(G976519)11547 0 R(G976520)11548 0 R(G976521)11549 0 R(G976522)11550 0 

>> R(G976523)11551 0 R(G976524)11552 0 R(G976524.004)11553 0 
> R(G976525)11554 
>> 0 R(G976550)11555 0 R(G976553)11556 0 R(G976554)11557 0 R(G976555)11558 

> 0 
>> R(G976558)11559 0 R(G976559)11560 0 R(G976560)11561 0 R]>>
>> endobj
>> 
>> % and that seems to show us that G976524 points to page 11552 0
>> 6266 0 obj<</First 6267 0 R/Parent 6260 0 R/Next 6265 0 
>> R/Dest(G976524)/Count 1/Last 6267 0 R/Prev 6268 0 R/Title(Classes)>>
>> endobj
>> 
>> % when we look at 11552, we find that it looks like our normal named 
>> destination
>> 11552 0 obj[25 0 R/XYZ 109 639 null]
>> endobj
>> 
>> % and 25 0 is, the actual page object, as we expected
>> 25 0 obj<</CropBox[53 63 557 729]/Parent 18988 0 R/B[4176 0 
>> R]/StructParents 6/Contents 27 0 R/Rotate 0/MediaBox[0 0 612 
>> 792]/Resources 26 0 R/Type/Page>>
>> endobj
>> 
>> 
>> Okay, so that PDF was non-conforming, but it was good enough that I'd 
>> expect PDFBox to be able to parse it.  Let's take a look at the output 
> and 
>> see what went wrong.
>> % we'll start at the trailer
>> trailer
>> <<
>> /Root 1 0 R
>> /ID [<78E9221F1CF4B2B411AC7654A2B830A0> 
>> <78E9221F1CF4B2B411AC7654A2B830A0>]
>> /Size 14095
>>>>
>> 
>> % then progress to the root
>> 1 0 obj
>> <<
>> /Type /Catalog
>> /Version /1.4
>> /Pages 2 0 R
>> /Outlines 3 0 R
>>>>
>> endobj
>> 
>> Ah ha, we don't have /Names, which means we can't have any named 
>> destinations.  Now, think about why this might be.  What did we copy 
> over 
>> when we made this new PDF?  Just the pages.  We didn't copy over the 
>> outline, nor any of the named destinations.  So I wouldn't say there's 
> any 
>> bug in PDFBox here (at least not based on what I've seen thus far). The 

> 
>> reason it worked in the previous file was because it wasn't a named 
>> destination which was used, it was a page reference and a specific x,y 
>> value.
>> 
>> The reason I went through this long example is to show you how I 
figured 
> 
>> out where the problem lies.  I hope that part was helpful.  I don't 
> really 
>> have an answer on how to fix this, but I can at least show you why it's 

>> breaking.  I'm pretty sure you know more about named destinations than 
I 
> 
>> do, so hopefully you can take this information and put it to good use. 
I 
> 
>> did just notice that PDFMergerUtility::appendDocument() handles the 
>> catalog Names.  You might be able to look there for an example. 
>> PDDocumentNameDictionary destNames = destCatalog.getNames();  I can't 
> say 
>> whether or not this will have all the information you're looking for or 

>> not, but it should at least be a good first step.
>> 
>> Let me know if you have any other questions.
>> 
>> ---- 
>> Thanks,
>> Adam
>> 
>> 
>> 
>> 
>> 
>> From:
>> "Hesham G." <he...@gmail.com>
>> To:
>> <us...@pdfbox.apache.org>
>> Date:
>> 09/04/2010 01:49
>> Subject:
>> Re: getting and setting names of named destinations
>> 
>> 
>> 
>> Adam ,
>> 
>> Thanks a lot for your time and effort.
>> 
>> The PDF sample you have downloaded is a small sample that I used a 
>> splitter program to split part of my big PDF so you can download it 
>> easily. I have tested this small PDF now and you are right it worked 
> fine 
>> ... I think the splitter did that fix.
>> 
>> But when I tried the same code on the original big PDF it did not work. 

> I 
>> tried PDFBox latest version 1.2.1 to test it. When I click on any of 
the 
> 
>> bookmarks, nothing happens.
>> If you have time please test the same code on the original PDF, here : 
>> http://www.4shared.com/document/hEKeK6PJ/Java_Studio_Creator_IDE.html
>> 
>> 
>> Best regards ,
>> Hesham 
>> 
>> ---------------------------------------------
>> Included message :
>> 
>>> Hesham,
>>> 
>>> The first thing I did was download the PDF and look at it.  That 
didn't 
> 
>>> help much since everything is compressed, so I decompressed it using 
>> pdftk 
>>> so it's human readable.  Then I found the object which links to a 
>> specific 
>>> place in a page, I chose the "Classes" bookmark.
>>> 
>>> 53 0 obj 
>>> <<
>>> /First 54 0 R
>>> /Title (Classes)
>>> /Parent 49 0 R
>>> /Dest [29 0 R /XYZ 109 639 null]
>>> /Count 1
>>> /Next 51 0 R
>>> /Last 54 0 R
>>> /Prev 52 0 R
>>>>>
>>> 
>>> The destination is "29 0 R" which is a page, and the XYZ is also set. 
I 
> 
>> 
>>> had to look that one up in the spec and found it in section 12.3.2.2. 
>> This 
>>> is the left, top, and zoom.  So the point 109,639 will be in the top 
>> left 
>>> corner when clicking the link.  At this point I at least know how it 
>>> works.  As a final test, I searched the PDF for "G917701" and did not 
>> find 
>>> anything.
>>> 
>>> Then I ran you sample code on the uncompressed file.  Before even 
>> opening 
>>> it with Adobe, I traced from the trailer -> root -> catalog -> through 

>> the 
>>> bookmarks until I got to object 77, which was the "Classes" bookmark. 
> It 
>> 
>>> looked correct, so I opened the file in Adobe Reader and it worked 
just 
> 
>>> fine.  This confirms that there is not a problem in importPage() under 

>> all 
>>> circumstances (if at all).
>>> 
>>> I then ran that same code with the original, compressed PDF and the 
>>> "Classes" bookmark worked fine.  So I'm unable to duplicate your test 
>>> results.  For reference, here's the object from the output file when 
>> using 
>>> the exact file I downloaded from your link:
>>> 76 0 obj
>>> <<
>>> /Next 62 0 R
>>> /Parent 44 0 R
>>> /Dest [86 0 R /XYZ 109 639 null]
>>> /Title (Classes)
>>> /Prev 77 0 R
>>> /Count 1
>>> /Last 89 0 R
>>> /First 89 0 R
>>>>>
>>> 
>>> I do not have enough time to look into this any further and try to 
>>> determine how to set named destinations, however I'll do my best to 
try 
> 
>> to 
>>> get you squared away with simple tests like this one.  If you're not 
>>> getting the same results as me with this simple test, it may be that 
>>> fixing this problem will also resolve other issues you're facing.
>>> 
>>> I'm using the latest code from SVN, which may be a difference between 
> my 
>> 
>>> system and yours.  So take a look at the objects in your output PDF 
>> (using 
>>> a decent text editor) and see if anything is different.  Trace around 
>> and 
>>> see if the destination page is actually a page object, and if it is 
>> listed 
>>> in the /Pages section.  If everything looks like it's correct in the 
>> file, 
>>> but the bookmark still doesn't work, post your output file somewhere 
>>> online and link us to it like you did with the example file below.
>>> 
>>> As long as I can run a quick test in just a few minutes (like your 
>> example 
>>> here) and know exactly what to look for, I should be able to take a 
>> look. 
>>> It's just when the code gets long and complex that it'll be an issue. 
> As 
>> 
>>> long as your reports are as short and concise as this one, I'm sure 
>> we'll 
>>> get it resolved quickly.
>>> 
>>> ---- 
>>> Thanks,
>>> Adam
>>> 
>>> 
>>> 
>>> 
>>> 
>>> From:
>>> Hesham Gneady <he...@gmail.com>
>>> To:
>>> users@pdfbox.apache.org
>>> Date:
>>> 09/02/2010 02:32
>>> Subject:
>>> Re: getting and setting names of named destinations
>>> 
>>> 
>>> 
>>> Kevin and Adam ,
>>> 
>>> I have made some tests and i am now sure of the problem ... The 
problem 
> 
>> is
>>> not in the method setNamedDestination( "G917701" );
>>> The main problem is if i use importPage(...) to copy/paste some pdf 
>> pages,
>>> then copy their bookmarks. Here is a code sample where i copy a PDF 
>> having
>>> Named destinations bookmarks to another new PDF :
>>> 
>>> public void copyPDFWithNDBookmarks() {
>>> String inputpath = "C:\\inputPDF.pdf";  // Has bookmarks with named
>>> destinations.
>>> String ouputpath = "C:\\outputPDF.pdf";
>>> try {
>>> PDDocument inputPDFFile = PDDocument.load( inputpath );
>>> PDDocument outputPDFFile = new PDDocument();
>>> List<PDPage> inputPDFPages =
>>> inputPDFFile.getDocumentCatalog().getAllPages();  // Get all pages of 
>> this
>>> PDF.
>>> // Copy/Paste all PDF pages :
>>>        for( PDPage page: inputPDFPages )
>>>        outputPDFFile.importPage( page );
>>> 
>>> // Copy/Paste all bookmarks
>>> PDDocumentOutline pdfBookmarks =
>>> inputPDFFile.getDocumentCatalog().getDocumentOutline();
>>> outputPDFFile.getDocumentCatalog().setDocumentOutline( pdfBookmarks );
>>> 
>>> outputPDFFile.save( ouputpath );
>>> outputPDFFile.close();
>>> } catch (IOException e) {
>>> e.printStackTrace();
>>> } catch (COSVisitorException e) {
>>> e.printStackTrace();
>>> }
>>> }
>>> 
>>> You can try this PDF as an input PDF:
>>> 
>> 
> 
http://www.4shared.com/document/XrPhJSCd/sample_pdf_having_bookmarks_wi.html

> 
>> 
>>> 
>>> When you open the output PDF and click any bookmark ... Nothing will 
>>> happen
>>> !
>>> I think this is a problem in PDFBox importPage(...) method.
>>> 
>>> Adam ... Can you please check this out ?
>>> I have checked the mailing list, and i see many people asking about 
the
>>> Named destinations, but they mostly reach a dead end.
>>> 
>>> Best regards ,
>>> Hesham
>>> 
>>> 
>>> On Wed, Sep 1, 2010 at 6:13 PM, Kevin Brown <kb...@gmail.com> wrote:
>>> 
>>>> Hesham,
>>>>
>>>> I'm sorry to mislead you. I looked at my notes and it turns out I 
> never
>>>> created them; I just edited them. So I a'm not sure I can help you. I 

>> am
>>>> very interested in this and will experiment with it next week.
>>>>
>>>> Has anyone out there been able to create named destinations using 
>>> pdfbox?
>>>>
>>>> Kevin
>>>>
>>>>
>>>> On Wed, Sep 1, 2010 at 10:04 AM, Hesham G. <he...@gmail.com> 
>>> wrote:
>>>>
>>>> > Strange ... I will try to dig in this, and I will be waiting your 
>>> reply
>>>> for
>>>> > more details if you can help.
>>>> > Happy trip ...
>>>> >
>>>> > Best regards ,
>>>> > Hesham
>>>> >
>>>> > ---------------------------------------------
>>>> > Included message :
>>>> >
>>>> > > No, I was able to get mine to work sorta... the named 
destinations 
> 
>>> are
>>>> > > problematic tho. I am sorry, but I am going out of town for a 
> week. 
>> 
>>> But
>>>> I
>>>> > > will post on this when I get back. Good luck.
>>>> > >
>>>> > > Kevin
>>>> > >
>>>> > >
>>>> > > On Wed, Sep 1, 2010 at 5:48 AM, Hesham G. 
<he...@gmail.com>
>>>> > wrote:
>>>> > >
>>>> > >> Kevin ,
>>>> > >>
>>>> > >> You said you were having problems setting a named destination. I 

>>> have
>>>> > tried
>>>> > >> to define a bookmark named destination but it didn't work.
>>>> > >> Here is my code :
>>>> > >> PDNamedDestination pn = new PDNamedDestination();
>>>> > >> pn.setNamedDestination( "G917701" );
>>>> > >> bookmark.setDestination( pn );
>>>> > >>
>>>> > >> When I open the PDF & click on that bookmark, nothing happens. I 

>>> have
>>>> a
>>>> > PDF
>>>> > >> editor that shows me the bookmark destinations ... So when I 
>> showed
>>>> the
>>>> > >> named destination for this bookmark, it was empty !
>>>> > >> Some how it was not set at all. Is this the problem you are 
> facing 
>> 
>>> ?
>>>> > >>
>>>> > >> Best regards ,
>>>> > >> Hesham
>>>> > >
>>>> >
>>>>
>>> 
>>> 
>>> 
>>> -- 
>>> Thanks ,
>>> Hesham Gneady
>>> Software Developer
>>> 
>>> 
>>> 
>>> ?  Click here to submit conditions 
>>> 
>>> This email and any content within or attached hereto from  Sun West 
>> Mortgage Company, Inc.  is confidential and/or legally privileged. The 
>> information is intended only for the use of the individual or entity 
> named 
>> on this email. If you are not the intended recipient, you are hereby 
>> notified that any disclosure, copying, distribution or the taking of 
any 
> 
>> action in reliance on the contents of this email information is 
strictly 
> 
>> prohibited, and that the documents should be returned to this office 
>> immediately by email. Receipt by anyone other than the intended 
> recipient 
>> is not a waiver of any privilege. Please do not include your social 
>> security number, account number, or any other personal or financial 
>> information in the content of the email. Should you have any questions, 

>> please call  (800) 453 7884.   =
>> 
>> 
>> ?  Click here to submit conditions 
>> 
>> This email and any content within or attached hereto from  Sun West 
> Mortgage Company, Inc.  is confidential and/or legally privileged. The 
> information is intended only for the use of the individual or entity 
named 
> on this email. If you are not the intended recipient, you are hereby 
> notified that any disclosure, copying, distribution or the taking of any 

> action in reliance on the contents of this email information is strictly 

> prohibited, and that the documents should be returned to this office 
> immediately by email. Receipt by anyone other than the intended 
recipient 
> is not a waiver of any privilege. Please do not include your social 
> security number, account number, or any other personal or financial 
> information in the content of the email. Should you have any questions, 
> please call  (800) 453 7884.   =
> 
> 
> ?  Click here to submit conditions 
> 
> This email and any content within or attached hereto from  Sun West 
Mortgage Company, Inc.  is confidential and/or legally privileged. The 
information is intended only for the use of the individual or entity named 
on this email. If you are not the intended recipient, you are hereby 
notified that any disclosure, copying, distribution or the taking of any 
action in reliance on the contents of this email information is strictly 
prohibited, and that the documents should be returned to this office 
immediately by email. Receipt by anyone other than the intended recipient 
is not a waiver of any privilege. Please do not include your social 
security number, account number, or any other personal or financial 
information in the content of the email. Should you have any questions, 
please call  (800) 453 7884.   =


?  Click here to submit conditions  

This email and any content within or attached hereto from  Sun West Mortgage Company, Inc.  is confidential and/or legally privileged. The information is intended only for the use of the individual or entity named on this email. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution or the taking of any action in reliance on the contents of this email information is strictly prohibited, and that the documents should be returned to this office immediately by email. Receipt by anyone other than the intended recipient is not a waiver of any privilege. Please do not include your social security number, account number, or any other personal or financial information in the content of the email. Should you have any questions, please call  (800) 453 7884.   

Re: getting and setting names of named destinations

Posted by "Hesham G." <he...@gmail.com>.
Adam ,

I agree with you that this is the logical thing.
But still ... After I copied the PDF with all its bookmarks, then I removed some pages, the bookmarks refer to the right location in the page, but to wrong pages.
Here is my code, you can try it on the PDF you have downloaded :

String inputpath = "C:\\inputPDF.pdf"; // Has bookmarks with named destinations.
String ouputpath = "C:\\outputPDF.pdf";
PDDocument inputPDFFile = PDDocument.load( inputpath );
PDDocument outputPDFFile = new PDDocument(); 
List<PDPage> inputPDFPages = inputPDFFile.getDocumentCatalog().getAllPages(); // Get all pages of this PDF.


// Copy/Paste all PDF pages :
for( PDPage page: inputPDFPages )
 outputPDFFile.importPage( page );

// Copy/Paste all Named destinations :
PDDocumentCatalog destCatalog = outputPDFFile.getDocumentCatalog();
PDDocumentCatalog srcCatalog = inputPDFFile.getDocumentCatalog();
COSName names = COSName.getPDFName( "Names" );
PDDocumentNameDictionary destNames = destCatalog.getNames();
PDDocumentNameDictionary srcNames = srcCatalog.getNames();

if( srcNames != null ) {
 if( destNames == null )
  destCatalog.getCOSDictionary().setItem(names, cloneForNewDocument(outputPDFFile, srcNames));
else
 destNames.getCOSDictionary().mergeInto((COSDictionary)cloneForNewDocument(outputPDFFile, srcNames));
}


// Copy/Paste all bookmarks :
PDDocumentOutline destOutline = destCatalog.getDocumentOutline();
PDDocumentOutline srcOutline = srcCatalog.getDocumentOutline();
if (srcOutline != null) {
 if (destOutline == null) {
  PDDocumentOutline cloned = new PDDocumentOutline((COSDictionary)cloneForNewDocument(outputPDFFile, srcOutline));
  destCatalog.setDocumentOutline(cloned);
 } else {
  PDOutlineItem first = srcOutline.getFirstChild();
  PDOutlineItem clonedFirst = new PDOutlineItem((COSDictionary)cloneForNewDocument( outputPDFFile, first));
  destOutline.appendChild(clonedFirst);
 }
}

// Remove some pages :
outputPDFFile.removePage( 25 ); 
outputPDFFile.removePage( 24 ); 
outputPDFFile.removePage( 23 ); 
outputPDFFile.removePage( 22 ); 
outputPDFFile.removePage( 21 ); 
outputPDFFile.removePage( 20 ); 

outputPDFFile.save( ouputpath );
outputPDFFile.close();



Best regards ,
Hesham

---------------------------------------------
Included message :

getting and setting names of named destinations

> "So if I want to remove a page from the PDF, all Named destinations must 
> be updated manually to refer to the new pages numbers..."
> 
> Not true.  The references are to not page numbers, but the actual object 
> IDs.  When you delete a page, it just drops out of the list of pages (and 
> may or may not delete the actual page object, depending on what software 
> you are using).  So the other pages don't change object ID nor revision 
> number.
> 
> ---- 
> Thanks,
> Adam
> 
> 
> 
> 
> 
> From:
> "Hesham G." <he...@gmail.com>
> To:
> <us...@pdfbox.apache.org>
> Date:
> 09/11/2010 02:20
> Subject:
> Re: getting and setting names of named destinations
> 
> 
> 
> Adam ,
> 
> Thanks a lot for the investigation, and for putting me on the right way. I 
> have copied the code that copies the Named destinations from the 
> 'PDFMergerUtility' code, and it worked fine. Here is my final code if any 
> body needs it :
> I have only 1 problem ... As I understand the Named destinations written 
> at the PDF trailer contains the ND, and the page it refers to, right ?
> So if I want to remove a page from the PDF, all Named destinations must be 
> updated manually to refer to the new pages numbers ... But how can I 
> update a bookmark page number, while keeping the Named destination as it 
> is ?
> 
> String inputpath = "C:\\inputPDF.pdf"; // Has bookmarks with named 
> destinations.
> 
> String ouputpath = "C:\\outputPDF.pdf";
> 
> PDDocument inputPDFFile = PDDocument.load( inputpath );
> 
> PDDocument outputPDFFile = new PDDocument(); 
> 
> List<PDPage> inputPDFPages = 
> inputPDFFile.getDocumentCatalog().getAllPages(); // Get all pages of this 
> PDF.
> 
> 
> // Copy/Paste all PDF pages :
> 
> for( PDPage page: inputPDFPages )
> 
> outputPDFFile.importPage( page );
> 
> 
> 
> // Copy/Paste all bookmarks(The old code) :
> 
> //PDDocumentOutline pdfBookmarks = 
> inputPDFFile.getDocumentCatalog().getDocumentOutline(); // The bookmarks 
> root object. 
> 
> //outputPDFFile.getDocumentCatalog().setDocumentOutline( pdfBookmarks );
> 
> 
> // Copy/Paste all Named destinations :
> 
> PDDocumentCatalog destCatalog = outputPDFFile.getDocumentCatalog();
> 
> PDDocumentCatalog srcCatalog = inputPDFFile.getDocumentCatalog();
> 
> 
> COSName names = COSName.getPDFName( "Names" );
> 
> PDDocumentNameDictionary destNames = destCatalog.getNames();
> 
> PDDocumentNameDictionary srcNames = srcCatalog.getNames();
> 
> if( srcNames != null ) {
> 
> if( destNames == null )
> 
> destCatalog.getCOSDictionary().setItem(names, 
> cloneForNewDocument(outputPDFFile, srcNames));
> 
> else
> 
> destNames.getCOSDictionary().mergeInto((COSDictionary) 
> cloneForNewDocument(outputPDFFile, srcNames));
> 
> }
> 
> 
> // Copy/Paste all bookmarks :
> 
> PDDocumentOutline destOutline = destCatalog.getDocumentOutline();
> 
> PDDocumentOutline srcOutline = srcCatalog.getDocumentOutline();
> 
> if (srcOutline != null) {
> 
> if (destOutline == null) {
> 
> PDDocumentOutline cloned = new PDDocumentOutline((COSDictionary) 
> cloneForNewDocument(outputPDFFile, srcOutline));
> 
> destCatalog.setDocumentOutline(cloned);
> 
> } else {
> 
> PDOutlineItem first = srcOutline.getFirstChild();
> 
> PDOutlineItem clonedFirst = new PDOutlineItem((COSDictionary) 
> cloneForNewDocument( outputPDFFile, first));
> 
> destOutline.appendChild(clonedFirst);
> 
> }
> 
> }
> 
> 
> //outputPDFFile.removePage( 21 ); // If we used this line it will cause 
> problems to the Named destinations.
> 
> 
> outputPDFFile.save( ouputpath );
> 
> outputPDFFile.close();
> 
> 
> 
> 
> Best regards ,
> Hesham 
> 
> 
> ---------------------------------------------
> Included message :
> 
>> Hesham,
>> 
>> Okay, I was now able to duplicate your findings.  Let's start with the 
>> input file and see how that's laid out.  We'll start with the trailer 
> and 
>> proceed from there:
>> 
>> trailer
>> <</Size 20655/Root 19148 0 R/Info 19146 0 
>> 
> R/ID[<ECD3B98C93AEB248888E61674A31F8CF><6362876D55F64E4FAE2312BC1294000B>]/Prev 
> 
>> 116 >>
>> 
>> % next we go to the root node
>> 19148 0 obj<</Names 19164 0 R/Outlines 5147 0 R/Metadata 19145 0 
>> R/AcroForm 19163 0 R/Pages 18985 0 R/Threads 19149 0 R/StructTreeRoot 
> 6272 
>> 0 R/Type/Catalog>>
>> endobj
>> 
>> % Note that 19148 0 appears multiple times, so we're dealing with a 
>> non-conforming PDF
>> % we move on to the Names object
>> 19164 0 obj<</Dests 7710 0 R>>
>> endobj
>> 
>> % then to Dests
>> 7710 0 obj<</Kids[7711 0 R 7712 0 R 7713 0 R 7714 0 R 7715 0 R 7716 0 
> R]>>
>> endobj
>> 
>> % we should go through all of these, but since I already found our 
> target 
>> bookmark ("Classes"), I'll skip straight to 7715 0
>> 7715 0 obj<</Limits[(G1061706)(I1.1011635)]/Kids[10024 0 R 10025 0 R 
> 10026 
>> 0 R 10027 0 R 10028 0 R 10029 0 R 10030 0 R 10031 0 R 10032 0 R 10033 0 
> R 
>> 10034 0 R 10035 0 R 10036 0 R 10037 0 R 10038 0 R 10039 0 R 10040 0 R 
>> 10041 0 R 10042 0 R 10043 0 R 10044 0 R 10045 0 R 10046 0 R 10047 0 R 
>> 10048 0 R 10049 0 R 10050 0 R 10051 0 R 10052 0 R 10053 0 R 10054 0 R 
>> 10055 0 R 10056 0 R 10057 0 R 10058 0 R 10059 0 R 10060 0 R 10061 0 R 
>> 10062 0 R 10063 0 R 10064 0 R 10065 0 R 10066 0 R 10067 0 R 10068 0 R 
>> 10069 0 R 10070 0 R 10071 0 R 10072 0 R 10073 0 R 10074 0 R 10075 0 R]>>
>> endobj
>> 
>> % again, normally we'd have to go through each of these, but since I 
> know 
>> where it's at, we'll skip right to 10041 0 (I cheated and found the 
>> bookmark and then worked backward to get to the document root)
>> 10041 0 obj<</Limits[(G976459.002)(G976560)]/Names[(G976459.002)11514 0 
>> R(G976459.003)11515 0 R(G976459.004)11516 0 R(G976459.005)11517 0 
>> R(G976460)11518 0 R(G976460.004)11519 0 R(G976461)11520 0 
>> R(G976461.000)11521 0 R(G976461.001)11522 0 R(G976462)11523 0 
>> R(G976462.000)11524 0 R(G976462.001)11525 0 R(G976462.002)11526 0 
>> R(G976462.003)11527 0 R(G976462.004)11528 0 R(G976462.005)11529 0 
>> R(G976463)11530 0 R(G976463.001)11531 0 R(G976463.002)11532 0 
>> R(G976463.003)11533 0 R(G976463.004)11534 0 R(G976463.005)11535 0 
>> R(G976463.006)11536 0 R(G976463.007)11537 0 R(G976463.008)11538 0 
>> R(G976478)11539 0 R(G976491)11540 0 R(G976502)11541 0 R(G976503)11542 0 
>> R(G976504)11543 0 R(G976511)11544 0 R(G976517)11545 0 R(G976518)11546 0 
>> R(G976519)11547 0 R(G976520)11548 0 R(G976521)11549 0 R(G976522)11550 0 
>> R(G976523)11551 0 R(G976524)11552 0 R(G976524.004)11553 0 
> R(G976525)11554 
>> 0 R(G976550)11555 0 R(G976553)11556 0 R(G976554)11557 0 R(G976555)11558 
> 0 
>> R(G976558)11559 0 R(G976559)11560 0 R(G976560)11561 0 R]>>
>> endobj
>> 
>> % and that seems to show us that G976524 points to page 11552 0
>> 6266 0 obj<</First 6267 0 R/Parent 6260 0 R/Next 6265 0 
>> R/Dest(G976524)/Count 1/Last 6267 0 R/Prev 6268 0 R/Title(Classes)>>
>> endobj
>> 
>> % when we look at 11552, we find that it looks like our normal named 
>> destination
>> 11552 0 obj[25 0 R/XYZ 109 639 null]
>> endobj
>> 
>> % and 25 0 is, the actual page object, as we expected
>> 25 0 obj<</CropBox[53 63 557 729]/Parent 18988 0 R/B[4176 0 
>> R]/StructParents 6/Contents 27 0 R/Rotate 0/MediaBox[0 0 612 
>> 792]/Resources 26 0 R/Type/Page>>
>> endobj
>> 
>> 
>> Okay, so that PDF was non-conforming, but it was good enough that I'd 
>> expect PDFBox to be able to parse it.  Let's take a look at the output 
> and 
>> see what went wrong.
>> % we'll start at the trailer
>> trailer
>> <<
>> /Root 1 0 R
>> /ID [<78E9221F1CF4B2B411AC7654A2B830A0> 
>> <78E9221F1CF4B2B411AC7654A2B830A0>]
>> /Size 14095
>>>>
>> 
>> % then progress to the root
>> 1 0 obj
>> <<
>> /Type /Catalog
>> /Version /1.4
>> /Pages 2 0 R
>> /Outlines 3 0 R
>>>>
>> endobj
>> 
>> Ah ha, we don't have /Names, which means we can't have any named 
>> destinations.  Now, think about why this might be.  What did we copy 
> over 
>> when we made this new PDF?  Just the pages.  We didn't copy over the 
>> outline, nor any of the named destinations.  So I wouldn't say there's 
> any 
>> bug in PDFBox here (at least not based on what I've seen thus far).  The 
> 
>> reason it worked in the previous file was because it wasn't a named 
>> destination which was used, it was a page reference and a specific x,y 
>> value.
>> 
>> The reason I went through this long example is to show you how I figured 
> 
>> out where the problem lies.  I hope that part was helpful.  I don't 
> really 
>> have an answer on how to fix this, but I can at least show you why it's 
>> breaking.  I'm pretty sure you know more about named destinations than I 
> 
>> do, so hopefully you can take this information and put it to good use. I 
> 
>> did just notice that PDFMergerUtility::appendDocument() handles the 
>> catalog Names.  You might be able to look there for an example. 
>> PDDocumentNameDictionary destNames = destCatalog.getNames();  I can't 
> say 
>> whether or not this will have all the information you're looking for or 
>> not, but it should at least be a good first step.
>> 
>> Let me know if you have any other questions.
>> 
>> ---- 
>> Thanks,
>> Adam
>> 
>> 
>> 
>> 
>> 
>> From:
>> "Hesham G." <he...@gmail.com>
>> To:
>> <us...@pdfbox.apache.org>
>> Date:
>> 09/04/2010 01:49
>> Subject:
>> Re: getting and setting names of named destinations
>> 
>> 
>> 
>> Adam ,
>> 
>> Thanks a lot for your time and effort.
>> 
>> The PDF sample you have downloaded is a small sample that I used a 
>> splitter program to split part of my big PDF so you can download it 
>> easily. I have tested this small PDF now and you are right it worked 
> fine 
>> ... I think the splitter did that fix.
>> 
>> But when I tried the same code on the original big PDF it did not work. 
> I 
>> tried PDFBox latest version 1.2.1 to test it. When I click on any of the 
> 
>> bookmarks, nothing happens.
>> If you have time please test the same code on the original PDF, here : 
>> http://www.4shared.com/document/hEKeK6PJ/Java_Studio_Creator_IDE.html
>> 
>> 
>> Best regards ,
>> Hesham 
>> 
>> ---------------------------------------------
>> Included message :
>> 
>>> Hesham,
>>> 
>>> The first thing I did was download the PDF and look at it.  That didn't 
> 
>>> help much since everything is compressed, so I decompressed it using 
>> pdftk 
>>> so it's human readable.  Then I found the object which links to a 
>> specific 
>>> place in a page, I chose the "Classes" bookmark.
>>> 
>>> 53 0 obj 
>>> <<
>>> /First 54 0 R
>>> /Title (Classes)
>>> /Parent 49 0 R
>>> /Dest [29 0 R /XYZ 109 639 null]
>>> /Count 1
>>> /Next 51 0 R
>>> /Last 54 0 R
>>> /Prev 52 0 R
>>>>>
>>> 
>>> The destination is "29 0 R" which is a page, and the XYZ is also set. I 
> 
>> 
>>> had to look that one up in the spec and found it in section 12.3.2.2. 
>> This 
>>> is the left, top, and zoom.  So the point 109,639 will be in the top 
>> left 
>>> corner when clicking the link.  At this point I at least know how it 
>>> works.  As a final test, I searched the PDF for "G917701" and did not 
>> find 
>>> anything.
>>> 
>>> Then I ran you sample code on the uncompressed file.  Before even 
>> opening 
>>> it with Adobe, I traced from the trailer -> root -> catalog -> through 
>> the 
>>> bookmarks until I got to object 77, which was the "Classes" bookmark. 
> It 
>> 
>>> looked correct, so I opened the file in Adobe Reader and it worked just 
> 
>>> fine.  This confirms that there is not a problem in importPage() under 
>> all 
>>> circumstances (if at all).
>>> 
>>> I then ran that same code with the original, compressed PDF and the 
>>> "Classes" bookmark worked fine.  So I'm unable to duplicate your test 
>>> results.  For reference, here's the object from the output file when 
>> using 
>>> the exact file I downloaded from your link:
>>> 76 0 obj
>>> <<
>>> /Next 62 0 R
>>> /Parent 44 0 R
>>> /Dest [86 0 R /XYZ 109 639 null]
>>> /Title (Classes)
>>> /Prev 77 0 R
>>> /Count 1
>>> /Last 89 0 R
>>> /First 89 0 R
>>>>>
>>> 
>>> I do not have enough time to look into this any further and try to 
>>> determine how to set named destinations, however I'll do my best to try 
> 
>> to 
>>> get you squared away with simple tests like this one.  If you're not 
>>> getting the same results as me with this simple test, it may be that 
>>> fixing this problem will also resolve other issues you're facing.
>>> 
>>> I'm using the latest code from SVN, which may be a difference between 
> my 
>> 
>>> system and yours.  So take a look at the objects in your output PDF 
>> (using 
>>> a decent text editor) and see if anything is different.  Trace around 
>> and 
>>> see if the destination page is actually a page object, and if it is 
>> listed 
>>> in the /Pages section.  If everything looks like it's correct in the 
>> file, 
>>> but the bookmark still doesn't work, post your output file somewhere 
>>> online and link us to it like you did with the example file below.
>>> 
>>> As long as I can run a quick test in just a few minutes (like your 
>> example 
>>> here) and know exactly what to look for, I should be able to take a 
>> look. 
>>> It's just when the code gets long and complex that it'll be an issue. 
> As 
>> 
>>> long as your reports are as short and concise as this one, I'm sure 
>> we'll 
>>> get it resolved quickly.
>>> 
>>> ---- 
>>> Thanks,
>>> Adam
>>> 
>>> 
>>> 
>>> 
>>> 
>>> From:
>>> Hesham Gneady <he...@gmail.com>
>>> To:
>>> users@pdfbox.apache.org
>>> Date:
>>> 09/02/2010 02:32
>>> Subject:
>>> Re: getting and setting names of named destinations
>>> 
>>> 
>>> 
>>> Kevin and Adam ,
>>> 
>>> I have made some tests and i am now sure of the problem ... The problem 
> 
>> is
>>> not in the method setNamedDestination( "G917701" );
>>> The main problem is if i use importPage(...) to copy/paste some pdf 
>> pages,
>>> then copy their bookmarks. Here is a code sample where i copy a PDF 
>> having
>>> Named destinations bookmarks to another new PDF :
>>> 
>>> public void copyPDFWithNDBookmarks() {
>>> String inputpath = "C:\\inputPDF.pdf";  // Has bookmarks with named
>>> destinations.
>>> String ouputpath = "C:\\outputPDF.pdf";
>>> try {
>>> PDDocument inputPDFFile = PDDocument.load( inputpath );
>>> PDDocument outputPDFFile = new PDDocument();
>>> List<PDPage> inputPDFPages =
>>> inputPDFFile.getDocumentCatalog().getAllPages();  // Get all pages of 
>> this
>>> PDF.
>>> // Copy/Paste all PDF pages :
>>>        for( PDPage page: inputPDFPages )
>>>        outputPDFFile.importPage( page );
>>> 
>>> // Copy/Paste all bookmarks
>>> PDDocumentOutline pdfBookmarks =
>>> inputPDFFile.getDocumentCatalog().getDocumentOutline();
>>> outputPDFFile.getDocumentCatalog().setDocumentOutline( pdfBookmarks );
>>> 
>>> outputPDFFile.save( ouputpath );
>>> outputPDFFile.close();
>>> } catch (IOException e) {
>>> e.printStackTrace();
>>> } catch (COSVisitorException e) {
>>> e.printStackTrace();
>>> }
>>> }
>>> 
>>> You can try this PDF as an input PDF:
>>> 
>> 
> http://www.4shared.com/document/XrPhJSCd/sample_pdf_having_bookmarks_wi.html
> 
>> 
>>> 
>>> When you open the output PDF and click any bookmark ... Nothing will 
>>> happen
>>> !
>>> I think this is a problem in PDFBox importPage(...) method.
>>> 
>>> Adam ... Can you please check this out ?
>>> I have checked the mailing list, and i see many people asking about the
>>> Named destinations, but they mostly reach a dead end.
>>> 
>>> Best regards ,
>>> Hesham
>>> 
>>> 
>>> On Wed, Sep 1, 2010 at 6:13 PM, Kevin Brown <kb...@gmail.com> wrote:
>>> 
>>>> Hesham,
>>>>
>>>> I'm sorry to mislead you. I looked at my notes and it turns out I 
> never
>>>> created them; I just edited them. So I a'm not sure I can help you. I 
>> am
>>>> very interested in this and will experiment with it next week.
>>>>
>>>> Has anyone out there been able to create named destinations using 
>>> pdfbox?
>>>>
>>>> Kevin
>>>>
>>>>
>>>> On Wed, Sep 1, 2010 at 10:04 AM, Hesham G. <he...@gmail.com> 
>>> wrote:
>>>>
>>>> > Strange ... I will try to dig in this, and I will be waiting your 
>>> reply
>>>> for
>>>> > more details if you can help.
>>>> > Happy trip ...
>>>> >
>>>> > Best regards ,
>>>> > Hesham
>>>> >
>>>> > ---------------------------------------------
>>>> > Included message :
>>>> >
>>>> > > No, I was able to get mine to work sorta... the named destinations 
> 
>>> are
>>>> > > problematic tho. I am sorry, but I am going out of town for a 
> week. 
>> 
>>> But
>>>> I
>>>> > > will post on this when I get back. Good luck.
>>>> > >
>>>> > > Kevin
>>>> > >
>>>> > >
>>>> > > On Wed, Sep 1, 2010 at 5:48 AM, Hesham G. <he...@gmail.com>
>>>> > wrote:
>>>> > >
>>>> > >> Kevin ,
>>>> > >>
>>>> > >> You said you were having problems setting a named destination. I 
>>> have
>>>> > tried
>>>> > >> to define a bookmark named destination but it didn't work.
>>>> > >> Here is my code :
>>>> > >> PDNamedDestination pn = new PDNamedDestination();
>>>> > >> pn.setNamedDestination( "G917701" );
>>>> > >> bookmark.setDestination( pn );
>>>> > >>
>>>> > >> When I open the PDF & click on that bookmark, nothing happens. I 
>>> have
>>>> a
>>>> > PDF
>>>> > >> editor that shows me the bookmark destinations ... So when I 
>> showed
>>>> the
>>>> > >> named destination for this bookmark, it was empty !
>>>> > >> Some how it was not set at all. Is this the problem you are 
> facing 
>> 
>>> ?
>>>> > >>
>>>> > >> Best regards ,
>>>> > >> Hesham
>>>> > >
>>>> >
>>>>
>>> 
>>> 
>>> 
>>> -- 
>>> Thanks ,
>>> Hesham Gneady
>>> Software Developer
>>> 
>>> 
>>> 
>>> ?  Click here to submit conditions 
>>> 
>>> This email and any content within or attached hereto from  Sun West 
>> Mortgage Company, Inc.  is confidential and/or legally privileged. The 
>> information is intended only for the use of the individual or entity 
> named 
>> on this email. If you are not the intended recipient, you are hereby 
>> notified that any disclosure, copying, distribution or the taking of any 
> 
>> action in reliance on the contents of this email information is strictly 
> 
>> prohibited, and that the documents should be returned to this office 
>> immediately by email. Receipt by anyone other than the intended 
> recipient 
>> is not a waiver of any privilege. Please do not include your social 
>> security number, account number, or any other personal or financial 
>> information in the content of the email. Should you have any questions, 
>> please call  (800) 453 7884.   =
>> 
>> 
>> ?  Click here to submit conditions 
>> 
>> This email and any content within or attached hereto from  Sun West 
> Mortgage Company, Inc.  is confidential and/or legally privileged. The 
> information is intended only for the use of the individual or entity named 
> on this email. If you are not the intended recipient, you are hereby 
> notified that any disclosure, copying, distribution or the taking of any 
> action in reliance on the contents of this email information is strictly 
> prohibited, and that the documents should be returned to this office 
> immediately by email. Receipt by anyone other than the intended recipient 
> is not a waiver of any privilege. Please do not include your social 
> security number, account number, or any other personal or financial 
> information in the content of the email. Should you have any questions, 
> please call  (800) 453 7884.   =
> 
> 
> ?  Click here to submit conditions  
> 
> This email and any content within or attached hereto from  Sun West Mortgage Company, Inc.  is confidential and/or legally privileged. The information is intended only for the use of the individual or entity named on this email. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution or the taking of any action in reliance on the contents of this email information is strictly prohibited, and that the documents should be returned to this office immediately by email. Receipt by anyone other than the intended recipient is not a waiver of any privilege. Please do not include your social security number, account number, or any other personal or financial information in the content of the email. Should you have any questions, please call  (800) 453 7884.   =

Re: getting and setting names of named destinations

Posted by Ad...@swmc.com.
"So if I want to remove a page from the PDF, all Named destinations must 
be updated manually to refer to the new pages numbers..."

Not true.  The references are to not page numbers, but the actual object 
IDs.  When you delete a page, it just drops out of the list of pages (and 
may or may not delete the actual page object, depending on what software 
you are using).  So the other pages don't change object ID nor revision 
number.

---- 
Thanks,
Adam





From:
"Hesham G." <he...@gmail.com>
To:
<us...@pdfbox.apache.org>
Date:
09/11/2010 02:20
Subject:
Re: getting and setting names of named destinations



Adam ,

Thanks a lot for the investigation, and for putting me on the right way. I 
have copied the code that copies the Named destinations from the 
'PDFMergerUtility' code, and it worked fine. Here is my final code if any 
body needs it :
I have only 1 problem ... As I understand the Named destinations written 
at the PDF trailer contains the ND, and the page it refers to, right ?
So if I want to remove a page from the PDF, all Named destinations must be 
updated manually to refer to the new pages numbers ... But how can I 
update a bookmark page number, while keeping the Named destination as it 
is ?

String inputpath = "C:\\inputPDF.pdf"; // Has bookmarks with named 
destinations.

String ouputpath = "C:\\outputPDF.pdf";

PDDocument inputPDFFile = PDDocument.load( inputpath );

PDDocument outputPDFFile = new PDDocument(); 

List<PDPage> inputPDFPages = 
inputPDFFile.getDocumentCatalog().getAllPages(); // Get all pages of this 
PDF.


// Copy/Paste all PDF pages :

for( PDPage page: inputPDFPages )

outputPDFFile.importPage( page );



// Copy/Paste all bookmarks(The old code) :

//PDDocumentOutline pdfBookmarks = 
inputPDFFile.getDocumentCatalog().getDocumentOutline(); // The bookmarks 
root object. 

//outputPDFFile.getDocumentCatalog().setDocumentOutline( pdfBookmarks );


// Copy/Paste all Named destinations :

PDDocumentCatalog destCatalog = outputPDFFile.getDocumentCatalog();

PDDocumentCatalog srcCatalog = inputPDFFile.getDocumentCatalog();


COSName names = COSName.getPDFName( "Names" );

PDDocumentNameDictionary destNames = destCatalog.getNames();

PDDocumentNameDictionary srcNames = srcCatalog.getNames();

if( srcNames != null ) {

if( destNames == null )

destCatalog.getCOSDictionary().setItem(names, 
cloneForNewDocument(outputPDFFile, srcNames));

else

destNames.getCOSDictionary().mergeInto((COSDictionary) 
cloneForNewDocument(outputPDFFile, srcNames));

}


// Copy/Paste all bookmarks :

PDDocumentOutline destOutline = destCatalog.getDocumentOutline();

PDDocumentOutline srcOutline = srcCatalog.getDocumentOutline();

if (srcOutline != null) {

if (destOutline == null) {

PDDocumentOutline cloned = new PDDocumentOutline((COSDictionary) 
cloneForNewDocument(outputPDFFile, srcOutline));

destCatalog.setDocumentOutline(cloned);

} else {

PDOutlineItem first = srcOutline.getFirstChild();

PDOutlineItem clonedFirst = new PDOutlineItem((COSDictionary) 
cloneForNewDocument( outputPDFFile, first));

destOutline.appendChild(clonedFirst);

}

}


//outputPDFFile.removePage( 21 ); // If we used this line it will cause 
problems to the Named destinations.


outputPDFFile.save( ouputpath );

outputPDFFile.close();




Best regards ,
Hesham 


---------------------------------------------
Included message :

> Hesham,
> 
> Okay, I was now able to duplicate your findings.  Let's start with the 
> input file and see how that's laid out.  We'll start with the trailer 
and 
> proceed from there:
> 
> trailer
> <</Size 20655/Root 19148 0 R/Info 19146 0 
> 
R/ID[<ECD3B98C93AEB248888E61674A31F8CF><6362876D55F64E4FAE2312BC1294000B>]/Prev 

> 116 >>
> 
> % next we go to the root node
> 19148 0 obj<</Names 19164 0 R/Outlines 5147 0 R/Metadata 19145 0 
> R/AcroForm 19163 0 R/Pages 18985 0 R/Threads 19149 0 R/StructTreeRoot 
6272 
> 0 R/Type/Catalog>>
> endobj
> 
> % Note that 19148 0 appears multiple times, so we're dealing with a 
> non-conforming PDF
> % we move on to the Names object
> 19164 0 obj<</Dests 7710 0 R>>
> endobj
> 
> % then to Dests
> 7710 0 obj<</Kids[7711 0 R 7712 0 R 7713 0 R 7714 0 R 7715 0 R 7716 0 
R]>>
> endobj
> 
> % we should go through all of these, but since I already found our 
target 
> bookmark ("Classes"), I'll skip straight to 7715 0
> 7715 0 obj<</Limits[(G1061706)(I1.1011635)]/Kids[10024 0 R 10025 0 R 
10026 
> 0 R 10027 0 R 10028 0 R 10029 0 R 10030 0 R 10031 0 R 10032 0 R 10033 0 
R 
> 10034 0 R 10035 0 R 10036 0 R 10037 0 R 10038 0 R 10039 0 R 10040 0 R 
> 10041 0 R 10042 0 R 10043 0 R 10044 0 R 10045 0 R 10046 0 R 10047 0 R 
> 10048 0 R 10049 0 R 10050 0 R 10051 0 R 10052 0 R 10053 0 R 10054 0 R 
> 10055 0 R 10056 0 R 10057 0 R 10058 0 R 10059 0 R 10060 0 R 10061 0 R 
> 10062 0 R 10063 0 R 10064 0 R 10065 0 R 10066 0 R 10067 0 R 10068 0 R 
> 10069 0 R 10070 0 R 10071 0 R 10072 0 R 10073 0 R 10074 0 R 10075 0 R]>>
> endobj
> 
> % again, normally we'd have to go through each of these, but since I 
know 
> where it's at, we'll skip right to 10041 0 (I cheated and found the 
> bookmark and then worked backward to get to the document root)
> 10041 0 obj<</Limits[(G976459.002)(G976560)]/Names[(G976459.002)11514 0 
> R(G976459.003)11515 0 R(G976459.004)11516 0 R(G976459.005)11517 0 
> R(G976460)11518 0 R(G976460.004)11519 0 R(G976461)11520 0 
> R(G976461.000)11521 0 R(G976461.001)11522 0 R(G976462)11523 0 
> R(G976462.000)11524 0 R(G976462.001)11525 0 R(G976462.002)11526 0 
> R(G976462.003)11527 0 R(G976462.004)11528 0 R(G976462.005)11529 0 
> R(G976463)11530 0 R(G976463.001)11531 0 R(G976463.002)11532 0 
> R(G976463.003)11533 0 R(G976463.004)11534 0 R(G976463.005)11535 0 
> R(G976463.006)11536 0 R(G976463.007)11537 0 R(G976463.008)11538 0 
> R(G976478)11539 0 R(G976491)11540 0 R(G976502)11541 0 R(G976503)11542 0 
> R(G976504)11543 0 R(G976511)11544 0 R(G976517)11545 0 R(G976518)11546 0 
> R(G976519)11547 0 R(G976520)11548 0 R(G976521)11549 0 R(G976522)11550 0 
> R(G976523)11551 0 R(G976524)11552 0 R(G976524.004)11553 0 
R(G976525)11554 
> 0 R(G976550)11555 0 R(G976553)11556 0 R(G976554)11557 0 R(G976555)11558 
0 
> R(G976558)11559 0 R(G976559)11560 0 R(G976560)11561 0 R]>>
> endobj
> 
> % and that seems to show us that G976524 points to page 11552 0
> 6266 0 obj<</First 6267 0 R/Parent 6260 0 R/Next 6265 0 
> R/Dest(G976524)/Count 1/Last 6267 0 R/Prev 6268 0 R/Title(Classes)>>
> endobj
> 
> % when we look at 11552, we find that it looks like our normal named 
> destination
> 11552 0 obj[25 0 R/XYZ 109 639 null]
> endobj
> 
> % and 25 0 is, the actual page object, as we expected
> 25 0 obj<</CropBox[53 63 557 729]/Parent 18988 0 R/B[4176 0 
> R]/StructParents 6/Contents 27 0 R/Rotate 0/MediaBox[0 0 612 
> 792]/Resources 26 0 R/Type/Page>>
> endobj
> 
> 
> Okay, so that PDF was non-conforming, but it was good enough that I'd 
> expect PDFBox to be able to parse it.  Let's take a look at the output 
and 
> see what went wrong.
> % we'll start at the trailer
> trailer
> <<
> /Root 1 0 R
> /ID [<78E9221F1CF4B2B411AC7654A2B830A0> 
> <78E9221F1CF4B2B411AC7654A2B830A0>]
> /Size 14095
>>>
> 
> % then progress to the root
> 1 0 obj
> <<
> /Type /Catalog
> /Version /1.4
> /Pages 2 0 R
> /Outlines 3 0 R
>>>
> endobj
> 
> Ah ha, we don't have /Names, which means we can't have any named 
> destinations.  Now, think about why this might be.  What did we copy 
over 
> when we made this new PDF?  Just the pages.  We didn't copy over the 
> outline, nor any of the named destinations.  So I wouldn't say there's 
any 
> bug in PDFBox here (at least not based on what I've seen thus far).  The 

> reason it worked in the previous file was because it wasn't a named 
> destination which was used, it was a page reference and a specific x,y 
> value.
> 
> The reason I went through this long example is to show you how I figured 

> out where the problem lies.  I hope that part was helpful.  I don't 
really 
> have an answer on how to fix this, but I can at least show you why it's 
> breaking.  I'm pretty sure you know more about named destinations than I 

> do, so hopefully you can take this information and put it to good use. I 

> did just notice that PDFMergerUtility::appendDocument() handles the 
> catalog Names.  You might be able to look there for an example. 
> PDDocumentNameDictionary destNames = destCatalog.getNames();  I can't 
say 
> whether or not this will have all the information you're looking for or 
> not, but it should at least be a good first step.
> 
> Let me know if you have any other questions.
> 
> ---- 
> Thanks,
> Adam
> 
> 
> 
> 
> 
> From:
> "Hesham G." <he...@gmail.com>
> To:
> <us...@pdfbox.apache.org>
> Date:
> 09/04/2010 01:49
> Subject:
> Re: getting and setting names of named destinations
> 
> 
> 
> Adam ,
> 
> Thanks a lot for your time and effort.
> 
> The PDF sample you have downloaded is a small sample that I used a 
> splitter program to split part of my big PDF so you can download it 
> easily. I have tested this small PDF now and you are right it worked 
fine 
> ... I think the splitter did that fix.
> 
> But when I tried the same code on the original big PDF it did not work. 
I 
> tried PDFBox latest version 1.2.1 to test it. When I click on any of the 

> bookmarks, nothing happens.
> If you have time please test the same code on the original PDF, here : 
> http://www.4shared.com/document/hEKeK6PJ/Java_Studio_Creator_IDE.html
> 
> 
> Best regards ,
> Hesham 
> 
> ---------------------------------------------
> Included message :
> 
>> Hesham,
>> 
>> The first thing I did was download the PDF and look at it.  That didn't 

>> help much since everything is compressed, so I decompressed it using 
> pdftk 
>> so it's human readable.  Then I found the object which links to a 
> specific 
>> place in a page, I chose the "Classes" bookmark.
>> 
>> 53 0 obj 
>> <<
>> /First 54 0 R
>> /Title (Classes)
>> /Parent 49 0 R
>> /Dest [29 0 R /XYZ 109 639 null]
>> /Count 1
>> /Next 51 0 R
>> /Last 54 0 R
>> /Prev 52 0 R
>>>>
>> 
>> The destination is "29 0 R" which is a page, and the XYZ is also set. I 

> 
>> had to look that one up in the spec and found it in section 12.3.2.2. 
> This 
>> is the left, top, and zoom.  So the point 109,639 will be in the top 
> left 
>> corner when clicking the link.  At this point I at least know how it 
>> works.  As a final test, I searched the PDF for "G917701" and did not 
> find 
>> anything.
>> 
>> Then I ran you sample code on the uncompressed file.  Before even 
> opening 
>> it with Adobe, I traced from the trailer -> root -> catalog -> through 
> the 
>> bookmarks until I got to object 77, which was the "Classes" bookmark. 
It 
> 
>> looked correct, so I opened the file in Adobe Reader and it worked just 

>> fine.  This confirms that there is not a problem in importPage() under 
> all 
>> circumstances (if at all).
>> 
>> I then ran that same code with the original, compressed PDF and the 
>> "Classes" bookmark worked fine.  So I'm unable to duplicate your test 
>> results.  For reference, here's the object from the output file when 
> using 
>> the exact file I downloaded from your link:
>> 76 0 obj
>> <<
>> /Next 62 0 R
>> /Parent 44 0 R
>> /Dest [86 0 R /XYZ 109 639 null]
>> /Title (Classes)
>> /Prev 77 0 R
>> /Count 1
>> /Last 89 0 R
>> /First 89 0 R
>>>>
>> 
>> I do not have enough time to look into this any further and try to 
>> determine how to set named destinations, however I'll do my best to try 

> to 
>> get you squared away with simple tests like this one.  If you're not 
>> getting the same results as me with this simple test, it may be that 
>> fixing this problem will also resolve other issues you're facing.
>> 
>> I'm using the latest code from SVN, which may be a difference between 
my 
> 
>> system and yours.  So take a look at the objects in your output PDF 
> (using 
>> a decent text editor) and see if anything is different.  Trace around 
> and 
>> see if the destination page is actually a page object, and if it is 
> listed 
>> in the /Pages section.  If everything looks like it's correct in the 
> file, 
>> but the bookmark still doesn't work, post your output file somewhere 
>> online and link us to it like you did with the example file below.
>> 
>> As long as I can run a quick test in just a few minutes (like your 
> example 
>> here) and know exactly what to look for, I should be able to take a 
> look. 
>> It's just when the code gets long and complex that it'll be an issue. 
As 
> 
>> long as your reports are as short and concise as this one, I'm sure 
> we'll 
>> get it resolved quickly.
>> 
>> ---- 
>> Thanks,
>> Adam
>> 
>> 
>> 
>> 
>> 
>> From:
>> Hesham Gneady <he...@gmail.com>
>> To:
>> users@pdfbox.apache.org
>> Date:
>> 09/02/2010 02:32
>> Subject:
>> Re: getting and setting names of named destinations
>> 
>> 
>> 
>> Kevin and Adam ,
>> 
>> I have made some tests and i am now sure of the problem ... The problem 

> is
>> not in the method setNamedDestination( "G917701" );
>> The main problem is if i use importPage(...) to copy/paste some pdf 
> pages,
>> then copy their bookmarks. Here is a code sample where i copy a PDF 
> having
>> Named destinations bookmarks to another new PDF :
>> 
>> public void copyPDFWithNDBookmarks() {
>> String inputpath = "C:\\inputPDF.pdf";  // Has bookmarks with named
>> destinations.
>> String ouputpath = "C:\\outputPDF.pdf";
>> try {
>> PDDocument inputPDFFile = PDDocument.load( inputpath );
>> PDDocument outputPDFFile = new PDDocument();
>> List<PDPage> inputPDFPages =
>> inputPDFFile.getDocumentCatalog().getAllPages();  // Get all pages of 
> this
>> PDF.
>> // Copy/Paste all PDF pages :
>>        for( PDPage page: inputPDFPages )
>>        outputPDFFile.importPage( page );
>> 
>> // Copy/Paste all bookmarks
>> PDDocumentOutline pdfBookmarks =
>> inputPDFFile.getDocumentCatalog().getDocumentOutline();
>> outputPDFFile.getDocumentCatalog().setDocumentOutline( pdfBookmarks );
>> 
>> outputPDFFile.save( ouputpath );
>> outputPDFFile.close();
>> } catch (IOException e) {
>> e.printStackTrace();
>> } catch (COSVisitorException e) {
>> e.printStackTrace();
>> }
>> }
>> 
>> You can try this PDF as an input PDF:
>> 
> 
http://www.4shared.com/document/XrPhJSCd/sample_pdf_having_bookmarks_wi.html

> 
>> 
>> When you open the output PDF and click any bookmark ... Nothing will 
>> happen
>> !
>> I think this is a problem in PDFBox importPage(...) method.
>> 
>> Adam ... Can you please check this out ?
>> I have checked the mailing list, and i see many people asking about the
>> Named destinations, but they mostly reach a dead end.
>> 
>> Best regards ,
>> Hesham
>> 
>> 
>> On Wed, Sep 1, 2010 at 6:13 PM, Kevin Brown <kb...@gmail.com> wrote:
>> 
>>> Hesham,
>>>
>>> I'm sorry to mislead you. I looked at my notes and it turns out I 
never
>>> created them; I just edited them. So I a'm not sure I can help you. I 
> am
>>> very interested in this and will experiment with it next week.
>>>
>>> Has anyone out there been able to create named destinations using 
>> pdfbox?
>>>
>>> Kevin
>>>
>>>
>>> On Wed, Sep 1, 2010 at 10:04 AM, Hesham G. <he...@gmail.com> 
>> wrote:
>>>
>>> > Strange ... I will try to dig in this, and I will be waiting your 
>> reply
>>> for
>>> > more details if you can help.
>>> > Happy trip ...
>>> >
>>> > Best regards ,
>>> > Hesham
>>> >
>>> > ---------------------------------------------
>>> > Included message :
>>> >
>>> > > No, I was able to get mine to work sorta... the named destinations 

>> are
>>> > > problematic tho. I am sorry, but I am going out of town for a 
week. 
> 
>> But
>>> I
>>> > > will post on this when I get back. Good luck.
>>> > >
>>> > > Kevin
>>> > >
>>> > >
>>> > > On Wed, Sep 1, 2010 at 5:48 AM, Hesham G. <he...@gmail.com>
>>> > wrote:
>>> > >
>>> > >> Kevin ,
>>> > >>
>>> > >> You said you were having problems setting a named destination. I 
>> have
>>> > tried
>>> > >> to define a bookmark named destination but it didn't work.
>>> > >> Here is my code :
>>> > >> PDNamedDestination pn = new PDNamedDestination();
>>> > >> pn.setNamedDestination( "G917701" );
>>> > >> bookmark.setDestination( pn );
>>> > >>
>>> > >> When I open the PDF & click on that bookmark, nothing happens. I 
>> have
>>> a
>>> > PDF
>>> > >> editor that shows me the bookmark destinations ... So when I 
> showed
>>> the
>>> > >> named destination for this bookmark, it was empty !
>>> > >> Some how it was not set at all. Is this the problem you are 
facing 
> 
>> ?
>>> > >>
>>> > >> Best regards ,
>>> > >> Hesham
>>> > >
>>> >
>>>
>> 
>> 
>> 
>> -- 
>> Thanks ,
>> Hesham Gneady
>> Software Developer
>> 
>> 
>> 
>> ?  Click here to submit conditions 
>> 
>> This email and any content within or attached hereto from  Sun West 
> Mortgage Company, Inc.  is confidential and/or legally privileged. The 
> information is intended only for the use of the individual or entity 
named 
> on this email. If you are not the intended recipient, you are hereby 
> notified that any disclosure, copying, distribution or the taking of any 

> action in reliance on the contents of this email information is strictly 

> prohibited, and that the documents should be returned to this office 
> immediately by email. Receipt by anyone other than the intended 
recipient 
> is not a waiver of any privilege. Please do not include your social 
> security number, account number, or any other personal or financial 
> information in the content of the email. Should you have any questions, 
> please call  (800) 453 7884.   =
> 
> 
> ?  Click here to submit conditions 
> 
> This email and any content within or attached hereto from  Sun West 
Mortgage Company, Inc.  is confidential and/or legally privileged. The 
information is intended only for the use of the individual or entity named 
on this email. If you are not the intended recipient, you are hereby 
notified that any disclosure, copying, distribution or the taking of any 
action in reliance on the contents of this email information is strictly 
prohibited, and that the documents should be returned to this office 
immediately by email. Receipt by anyone other than the intended recipient 
is not a waiver of any privilege. Please do not include your social 
security number, account number, or any other personal or financial 
information in the content of the email. Should you have any questions, 
please call  (800) 453 7884.   =


?  Click here to submit conditions  

This email and any content within or attached hereto from  Sun West Mortgage Company, Inc.  is confidential and/or legally privileged. The information is intended only for the use of the individual or entity named on this email. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution or the taking of any action in reliance on the contents of this email information is strictly prohibited, and that the documents should be returned to this office immediately by email. Receipt by anyone other than the intended recipient is not a waiver of any privilege. Please do not include your social security number, account number, or any other personal or financial information in the content of the email. Should you have any questions, please call  (800) 453 7884.   

Re: getting and setting names of named destinations

Posted by "Hesham G." <he...@gmail.com>.
Adam ,

Thanks a lot for the investigation, and for putting me on the right way. I have copied the code that copies the Named destinations from the 'PDFMergerUtility' code, and it worked fine. Here is my final code if any body needs it :
I have only 1 problem ... As I understand the Named destinations written at the PDF trailer contains the ND, and the page it refers to, right ?
So if I want to remove a page from the PDF, all Named destinations must be updated manually to refer to the new pages numbers ... But how can I update a bookmark page number, while keeping the Named destination as it is ?

String inputpath = "C:\\inputPDF.pdf"; // Has bookmarks with named destinations.

String ouputpath = "C:\\outputPDF.pdf";

PDDocument inputPDFFile = PDDocument.load( inputpath );

PDDocument outputPDFFile = new PDDocument(); 

List<PDPage> inputPDFPages = inputPDFFile.getDocumentCatalog().getAllPages(); // Get all pages of this PDF.


// Copy/Paste all PDF pages :

for( PDPage page: inputPDFPages )

outputPDFFile.importPage( page );



// Copy/Paste all bookmarks(The old code) :

//PDDocumentOutline pdfBookmarks = inputPDFFile.getDocumentCatalog().getDocumentOutline(); // The bookmarks root object. 

//outputPDFFile.getDocumentCatalog().setDocumentOutline( pdfBookmarks );


// Copy/Paste all Named destinations :

PDDocumentCatalog destCatalog = outputPDFFile.getDocumentCatalog();

PDDocumentCatalog srcCatalog = inputPDFFile.getDocumentCatalog();


COSName names = COSName.getPDFName( "Names" );

PDDocumentNameDictionary destNames = destCatalog.getNames();

PDDocumentNameDictionary srcNames = srcCatalog.getNames();

if( srcNames != null ) {

if( destNames == null )

destCatalog.getCOSDictionary().setItem(names, cloneForNewDocument(outputPDFFile, srcNames));

else

destNames.getCOSDictionary().mergeInto((COSDictionary) cloneForNewDocument(outputPDFFile, srcNames));

}


// Copy/Paste all bookmarks :

PDDocumentOutline destOutline = destCatalog.getDocumentOutline();

PDDocumentOutline srcOutline = srcCatalog.getDocumentOutline();

if (srcOutline != null) {

if (destOutline == null) {

PDDocumentOutline cloned = new PDDocumentOutline((COSDictionary) cloneForNewDocument(outputPDFFile, srcOutline));

destCatalog.setDocumentOutline(cloned);

} else {

PDOutlineItem first = srcOutline.getFirstChild();

PDOutlineItem clonedFirst = new PDOutlineItem((COSDictionary) cloneForNewDocument( outputPDFFile, first));

destOutline.appendChild(clonedFirst);

}

}


//outputPDFFile.removePage( 21 ); // If we used this line it will cause problems to the Named destinations.


outputPDFFile.save( ouputpath );

outputPDFFile.close();




Best regards ,
Hesham 


---------------------------------------------
Included message :

> Hesham,
> 
> Okay, I was now able to duplicate your findings.  Let's start with the 
> input file and see how that's laid out.  We'll start with the trailer and 
> proceed from there:
> 
> trailer
> <</Size 20655/Root 19148 0 R/Info 19146 0 
> R/ID[<ECD3B98C93AEB248888E61674A31F8CF><6362876D55F64E4FAE2312BC1294000B>]/Prev 
> 116 >>
> 
> % next we go to the root node
> 19148 0 obj<</Names 19164 0 R/Outlines 5147 0 R/Metadata 19145 0 
> R/AcroForm 19163 0 R/Pages 18985 0 R/Threads 19149 0 R/StructTreeRoot 6272 
> 0 R/Type/Catalog>>
> endobj
> 
> % Note that 19148 0 appears multiple times, so we're dealing with a 
> non-conforming PDF
> % we move on to the Names object
> 19164 0 obj<</Dests 7710 0 R>>
> endobj
> 
> % then to Dests
> 7710 0 obj<</Kids[7711 0 R 7712 0 R 7713 0 R 7714 0 R 7715 0 R 7716 0 R]>>
> endobj
> 
> % we should go through all of these, but since I already found our target 
> bookmark ("Classes"), I'll skip straight to 7715 0
> 7715 0 obj<</Limits[(G1061706)(I1.1011635)]/Kids[10024 0 R 10025 0 R 10026 
> 0 R 10027 0 R 10028 0 R 10029 0 R 10030 0 R 10031 0 R 10032 0 R 10033 0 R 
> 10034 0 R 10035 0 R 10036 0 R 10037 0 R 10038 0 R 10039 0 R 10040 0 R 
> 10041 0 R 10042 0 R 10043 0 R 10044 0 R 10045 0 R 10046 0 R 10047 0 R 
> 10048 0 R 10049 0 R 10050 0 R 10051 0 R 10052 0 R 10053 0 R 10054 0 R 
> 10055 0 R 10056 0 R 10057 0 R 10058 0 R 10059 0 R 10060 0 R 10061 0 R 
> 10062 0 R 10063 0 R 10064 0 R 10065 0 R 10066 0 R 10067 0 R 10068 0 R 
> 10069 0 R 10070 0 R 10071 0 R 10072 0 R 10073 0 R 10074 0 R 10075 0 R]>>
> endobj
> 
> % again, normally we'd have to go through each of these, but since I know 
> where it's at, we'll skip right to 10041 0 (I cheated and found the 
> bookmark and then worked backward to get to the document root)
> 10041 0 obj<</Limits[(G976459.002)(G976560)]/Names[(G976459.002)11514 0 
> R(G976459.003)11515 0 R(G976459.004)11516 0 R(G976459.005)11517 0 
> R(G976460)11518 0 R(G976460.004)11519 0 R(G976461)11520 0 
> R(G976461.000)11521 0 R(G976461.001)11522 0 R(G976462)11523 0 
> R(G976462.000)11524 0 R(G976462.001)11525 0 R(G976462.002)11526 0 
> R(G976462.003)11527 0 R(G976462.004)11528 0 R(G976462.005)11529 0 
> R(G976463)11530 0 R(G976463.001)11531 0 R(G976463.002)11532 0 
> R(G976463.003)11533 0 R(G976463.004)11534 0 R(G976463.005)11535 0 
> R(G976463.006)11536 0 R(G976463.007)11537 0 R(G976463.008)11538 0 
> R(G976478)11539 0 R(G976491)11540 0 R(G976502)11541 0 R(G976503)11542 0 
> R(G976504)11543 0 R(G976511)11544 0 R(G976517)11545 0 R(G976518)11546 0 
> R(G976519)11547 0 R(G976520)11548 0 R(G976521)11549 0 R(G976522)11550 0 
> R(G976523)11551 0 R(G976524)11552 0 R(G976524.004)11553 0 R(G976525)11554 
> 0 R(G976550)11555 0 R(G976553)11556 0 R(G976554)11557 0 R(G976555)11558 0 
> R(G976558)11559 0 R(G976559)11560 0 R(G976560)11561 0 R]>>
> endobj
> 
> % and that seems to show us that G976524 points to page 11552 0
> 6266 0 obj<</First 6267 0 R/Parent 6260 0 R/Next 6265 0 
> R/Dest(G976524)/Count 1/Last 6267 0 R/Prev 6268 0 R/Title(Classes)>>
> endobj
> 
> % when we look at 11552, we find that it looks like our normal named 
> destination
> 11552 0 obj[25 0 R/XYZ 109 639 null]
> endobj
> 
> % and 25 0 is, the actual page object, as we expected
> 25 0 obj<</CropBox[53 63 557 729]/Parent 18988 0 R/B[4176 0 
> R]/StructParents 6/Contents 27 0 R/Rotate 0/MediaBox[0 0 612 
> 792]/Resources 26 0 R/Type/Page>>
> endobj
> 
> 
> Okay, so that PDF was non-conforming, but it was good enough that I'd 
> expect PDFBox to be able to parse it.  Let's take a look at the output and 
> see what went wrong.
> % we'll start at the trailer
> trailer
> <<
> /Root 1 0 R
> /ID [<78E9221F1CF4B2B411AC7654A2B830A0> 
> <78E9221F1CF4B2B411AC7654A2B830A0>]
> /Size 14095
>>>
> 
> % then progress to the root
> 1 0 obj
> <<
> /Type /Catalog
> /Version /1.4
> /Pages 2 0 R
> /Outlines 3 0 R
>>>
> endobj
> 
> Ah ha, we don't have /Names, which means we can't have any named 
> destinations.  Now, think about why this might be.  What did we copy over 
> when we made this new PDF?  Just the pages.  We didn't copy over the 
> outline, nor any of the named destinations.  So I wouldn't say there's any 
> bug in PDFBox here (at least not based on what I've seen thus far).  The 
> reason it worked in the previous file was because it wasn't a named 
> destination which was used, it was a page reference and a specific x,y 
> value.
> 
> The reason I went through this long example is to show you how I figured 
> out where the problem lies.  I hope that part was helpful.  I don't really 
> have an answer on how to fix this, but I can at least show you why it's 
> breaking.  I'm pretty sure you know more about named destinations than I 
> do, so hopefully you can take this information and put it to good use.  I 
> did just notice that PDFMergerUtility::appendDocument() handles the 
> catalog Names.  You might be able to look there for an example. 
> PDDocumentNameDictionary destNames = destCatalog.getNames();  I can't say 
> whether or not this will have all the information you're looking for or 
> not, but it should at least be a good first step.
> 
> Let me know if you have any other questions.
> 
> ---- 
> Thanks,
> Adam
> 
> 
> 
> 
> 
> From:
> "Hesham G." <he...@gmail.com>
> To:
> <us...@pdfbox.apache.org>
> Date:
> 09/04/2010 01:49
> Subject:
> Re: getting and setting names of named destinations
> 
> 
> 
> Adam ,
> 
> Thanks a lot for your time and effort.
> 
> The PDF sample you have downloaded is a small sample that I used a 
> splitter program to split part of my big PDF so you can download it 
> easily. I have tested this small PDF now and you are right it worked fine 
> ... I think the splitter did that fix.
> 
> But when I tried the same code on the original big PDF it did not work. I 
> tried PDFBox latest version 1.2.1 to test it. When I click on any of the 
> bookmarks, nothing happens.
> If you have time please test the same code on the original PDF, here : 
> http://www.4shared.com/document/hEKeK6PJ/Java_Studio_Creator_IDE.html
> 
> 
> Best regards ,
> Hesham 
> 
> ---------------------------------------------
> Included message :
> 
>> Hesham,
>> 
>> The first thing I did was download the PDF and look at it.  That didn't 
>> help much since everything is compressed, so I decompressed it using 
> pdftk 
>> so it's human readable.  Then I found the object which links to a 
> specific 
>> place in a page, I chose the "Classes" bookmark.
>> 
>> 53 0 obj 
>> <<
>> /First 54 0 R
>> /Title (Classes)
>> /Parent 49 0 R
>> /Dest [29 0 R /XYZ 109 639 null]
>> /Count 1
>> /Next 51 0 R
>> /Last 54 0 R
>> /Prev 52 0 R
>>>>
>> 
>> The destination is "29 0 R" which is a page, and the XYZ is also set.  I 
> 
>> had to look that one up in the spec and found it in section 12.3.2.2. 
> This 
>> is the left, top, and zoom.  So the point 109,639 will be in the top 
> left 
>> corner when clicking the link.  At this point I at least know how it 
>> works.  As a final test, I searched the PDF for "G917701" and did not 
> find 
>> anything.
>> 
>> Then I ran you sample code on the uncompressed file.  Before even 
> opening 
>> it with Adobe, I traced from the trailer -> root -> catalog -> through 
> the 
>> bookmarks until I got to object 77, which was the "Classes" bookmark. It 
> 
>> looked correct, so I opened the file in Adobe Reader and it worked just 
>> fine.  This confirms that there is not a problem in importPage() under 
> all 
>> circumstances (if at all).
>> 
>> I then ran that same code with the original, compressed PDF and the 
>> "Classes" bookmark worked fine.  So I'm unable to duplicate your test 
>> results.  For reference, here's the object from the output file when 
> using 
>> the exact file I downloaded from your link:
>> 76 0 obj
>> <<
>> /Next 62 0 R
>> /Parent 44 0 R
>> /Dest [86 0 R /XYZ 109 639 null]
>> /Title (Classes)
>> /Prev 77 0 R
>> /Count 1
>> /Last 89 0 R
>> /First 89 0 R
>>>>
>> 
>> I do not have enough time to look into this any further and try to 
>> determine how to set named destinations, however I'll do my best to try 
> to 
>> get you squared away with simple tests like this one.  If you're not 
>> getting the same results as me with this simple test, it may be that 
>> fixing this problem will also resolve other issues you're facing.
>> 
>> I'm using the latest code from SVN, which may be a difference between my 
> 
>> system and yours.  So take a look at the objects in your output PDF 
> (using 
>> a decent text editor) and see if anything is different.  Trace around 
> and 
>> see if the destination page is actually a page object, and if it is 
> listed 
>> in the /Pages section.  If everything looks like it's correct in the 
> file, 
>> but the bookmark still doesn't work, post your output file somewhere 
>> online and link us to it like you did with the example file below.
>> 
>> As long as I can run a quick test in just a few minutes (like your 
> example 
>> here) and know exactly what to look for, I should be able to take a 
> look. 
>> It's just when the code gets long and complex that it'll be an issue. As 
> 
>> long as your reports are as short and concise as this one, I'm sure 
> we'll 
>> get it resolved quickly.
>> 
>> ---- 
>> Thanks,
>> Adam
>> 
>> 
>> 
>> 
>> 
>> From:
>> Hesham Gneady <he...@gmail.com>
>> To:
>> users@pdfbox.apache.org
>> Date:
>> 09/02/2010 02:32
>> Subject:
>> Re: getting and setting names of named destinations
>> 
>> 
>> 
>> Kevin and Adam ,
>> 
>> I have made some tests and i am now sure of the problem ... The problem 
> is
>> not in the method setNamedDestination( "G917701" );
>> The main problem is if i use importPage(...) to copy/paste some pdf 
> pages,
>> then copy their bookmarks. Here is a code sample where i copy a PDF 
> having
>> Named destinations bookmarks to another new PDF :
>> 
>> public void copyPDFWithNDBookmarks() {
>> String inputpath = "C:\\inputPDF.pdf";  // Has bookmarks with named
>> destinations.
>> String ouputpath = "C:\\outputPDF.pdf";
>> try {
>> PDDocument inputPDFFile = PDDocument.load( inputpath );
>> PDDocument outputPDFFile = new PDDocument();
>> List<PDPage> inputPDFPages =
>> inputPDFFile.getDocumentCatalog().getAllPages();  // Get all pages of 
> this
>> PDF.
>> // Copy/Paste all PDF pages :
>>        for( PDPage page: inputPDFPages )
>>        outputPDFFile.importPage( page );
>> 
>> // Copy/Paste all bookmarks
>> PDDocumentOutline pdfBookmarks =
>> inputPDFFile.getDocumentCatalog().getDocumentOutline();
>> outputPDFFile.getDocumentCatalog().setDocumentOutline( pdfBookmarks );
>> 
>> outputPDFFile.save( ouputpath );
>> outputPDFFile.close();
>> } catch (IOException e) {
>> e.printStackTrace();
>> } catch (COSVisitorException e) {
>> e.printStackTrace();
>> }
>> }
>> 
>> You can try this PDF as an input PDF:
>> 
> http://www.4shared.com/document/XrPhJSCd/sample_pdf_having_bookmarks_wi.html
> 
>> 
>> When you open the output PDF and click any bookmark ... Nothing will 
>> happen
>> !
>> I think this is a problem in PDFBox importPage(...) method.
>> 
>> Adam ... Can you please check this out ?
>> I have checked the mailing list, and i see many people asking about the
>> Named destinations, but they mostly reach a dead end.
>> 
>> Best regards ,
>> Hesham
>> 
>> 
>> On Wed, Sep 1, 2010 at 6:13 PM, Kevin Brown <kb...@gmail.com> wrote:
>> 
>>> Hesham,
>>>
>>> I'm sorry to mislead you. I looked at my notes and it turns out I never
>>> created them; I just edited them. So I a'm not sure I can help you. I 
> am
>>> very interested in this and will experiment with it next week.
>>>
>>> Has anyone out there been able to create named destinations using 
>> pdfbox?
>>>
>>> Kevin
>>>
>>>
>>> On Wed, Sep 1, 2010 at 10:04 AM, Hesham G. <he...@gmail.com> 
>> wrote:
>>>
>>> > Strange ... I will try to dig in this, and I will be waiting your 
>> reply
>>> for
>>> > more details if you can help.
>>> > Happy trip ...
>>> >
>>> > Best regards ,
>>> > Hesham
>>> >
>>> > ---------------------------------------------
>>> > Included message :
>>> >
>>> > > No, I was able to get mine to work sorta... the named destinations 
>> are
>>> > > problematic tho. I am sorry, but I am going out of town for a week. 
> 
>> But
>>> I
>>> > > will post on this when I get back. Good luck.
>>> > >
>>> > > Kevin
>>> > >
>>> > >
>>> > > On Wed, Sep 1, 2010 at 5:48 AM, Hesham G. <he...@gmail.com>
>>> > wrote:
>>> > >
>>> > >> Kevin ,
>>> > >>
>>> > >> You said you were having problems setting a named destination. I 
>> have
>>> > tried
>>> > >> to define a bookmark named destination but it didn't work.
>>> > >> Here is my code :
>>> > >> PDNamedDestination pn = new PDNamedDestination();
>>> > >> pn.setNamedDestination( "G917701" );
>>> > >> bookmark.setDestination( pn );
>>> > >>
>>> > >> When I open the PDF & click on that bookmark, nothing happens. I 
>> have
>>> a
>>> > PDF
>>> > >> editor that shows me the bookmark destinations ... So when I 
> showed
>>> the
>>> > >> named destination for this bookmark, it was empty !
>>> > >> Some how it was not set at all. Is this the problem you are facing 
> 
>> ?
>>> > >>
>>> > >> Best regards ,
>>> > >> Hesham
>>> > >
>>> >
>>>
>> 
>> 
>> 
>> -- 
>> Thanks ,
>> Hesham Gneady
>> Software Developer
>> 
>> 
>> 
>> ?  Click here to submit conditions 
>> 
>> This email and any content within or attached hereto from  Sun West 
> Mortgage Company, Inc.  is confidential and/or legally privileged. The 
> information is intended only for the use of the individual or entity named 
> on this email. If you are not the intended recipient, you are hereby 
> notified that any disclosure, copying, distribution or the taking of any 
> action in reliance on the contents of this email information is strictly 
> prohibited, and that the documents should be returned to this office 
> immediately by email. Receipt by anyone other than the intended recipient 
> is not a waiver of any privilege. Please do not include your social 
> security number, account number, or any other personal or financial 
> information in the content of the email. Should you have any questions, 
> please call  (800) 453 7884.   =
> 
> 
> ?  Click here to submit conditions  
> 
> This email and any content within or attached hereto from  Sun West Mortgage Company, Inc.  is confidential and/or legally privileged. The information is intended only for the use of the individual or entity named on this email. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution or the taking of any action in reliance on the contents of this email information is strictly prohibited, and that the documents should be returned to this office immediately by email. Receipt by anyone other than the intended recipient is not a waiver of any privilege. Please do not include your social security number, account number, or any other personal or financial information in the content of the email. Should you have any questions, please call  (800) 453 7884.   =

Re: getting and setting names of named destinations

Posted by Ad...@swmc.com.
Hesham,

Okay, I was now able to duplicate your findings.  Let's start with the 
input file and see how that's laid out.  We'll start with the trailer and 
proceed from there:

trailer
<</Size 20655/Root 19148 0 R/Info 19146 0 
R/ID[<ECD3B98C93AEB248888E61674A31F8CF><6362876D55F64E4FAE2312BC1294000B>]/Prev 
116 >>

% next we go to the root node
19148 0 obj<</Names 19164 0 R/Outlines 5147 0 R/Metadata 19145 0 
R/AcroForm 19163 0 R/Pages 18985 0 R/Threads 19149 0 R/StructTreeRoot 6272 
0 R/Type/Catalog>>
endobj

% Note that 19148 0 appears multiple times, so we're dealing with a 
non-conforming PDF
% we move on to the Names object
19164 0 obj<</Dests 7710 0 R>>
endobj

% then to Dests
7710 0 obj<</Kids[7711 0 R 7712 0 R 7713 0 R 7714 0 R 7715 0 R 7716 0 R]>>
endobj

% we should go through all of these, but since I already found our target 
bookmark ("Classes"), I'll skip straight to 7715 0
7715 0 obj<</Limits[(G1061706)(I1.1011635)]/Kids[10024 0 R 10025 0 R 10026 
0 R 10027 0 R 10028 0 R 10029 0 R 10030 0 R 10031 0 R 10032 0 R 10033 0 R 
10034 0 R 10035 0 R 10036 0 R 10037 0 R 10038 0 R 10039 0 R 10040 0 R 
10041 0 R 10042 0 R 10043 0 R 10044 0 R 10045 0 R 10046 0 R 10047 0 R 
10048 0 R 10049 0 R 10050 0 R 10051 0 R 10052 0 R 10053 0 R 10054 0 R 
10055 0 R 10056 0 R 10057 0 R 10058 0 R 10059 0 R 10060 0 R 10061 0 R 
10062 0 R 10063 0 R 10064 0 R 10065 0 R 10066 0 R 10067 0 R 10068 0 R 
10069 0 R 10070 0 R 10071 0 R 10072 0 R 10073 0 R 10074 0 R 10075 0 R]>>
endobj

% again, normally we'd have to go through each of these, but since I know 
where it's at, we'll skip right to 10041 0 (I cheated and found the 
bookmark and then worked backward to get to the document root)
10041 0 obj<</Limits[(G976459.002)(G976560)]/Names[(G976459.002)11514 0 
R(G976459.003)11515 0 R(G976459.004)11516 0 R(G976459.005)11517 0 
R(G976460)11518 0 R(G976460.004)11519 0 R(G976461)11520 0 
R(G976461.000)11521 0 R(G976461.001)11522 0 R(G976462)11523 0 
R(G976462.000)11524 0 R(G976462.001)11525 0 R(G976462.002)11526 0 
R(G976462.003)11527 0 R(G976462.004)11528 0 R(G976462.005)11529 0 
R(G976463)11530 0 R(G976463.001)11531 0 R(G976463.002)11532 0 
R(G976463.003)11533 0 R(G976463.004)11534 0 R(G976463.005)11535 0 
R(G976463.006)11536 0 R(G976463.007)11537 0 R(G976463.008)11538 0 
R(G976478)11539 0 R(G976491)11540 0 R(G976502)11541 0 R(G976503)11542 0 
R(G976504)11543 0 R(G976511)11544 0 R(G976517)11545 0 R(G976518)11546 0 
R(G976519)11547 0 R(G976520)11548 0 R(G976521)11549 0 R(G976522)11550 0 
R(G976523)11551 0 R(G976524)11552 0 R(G976524.004)11553 0 R(G976525)11554 
0 R(G976550)11555 0 R(G976553)11556 0 R(G976554)11557 0 R(G976555)11558 0 
R(G976558)11559 0 R(G976559)11560 0 R(G976560)11561 0 R]>>
endobj

% and that seems to show us that G976524 points to page 11552 0
6266 0 obj<</First 6267 0 R/Parent 6260 0 R/Next 6265 0 
R/Dest(G976524)/Count 1/Last 6267 0 R/Prev 6268 0 R/Title(Classes)>>
endobj

% when we look at 11552, we find that it looks like our normal named 
destination
11552 0 obj[25 0 R/XYZ 109 639 null]
endobj

% and 25 0 is, the actual page object, as we expected
25 0 obj<</CropBox[53 63 557 729]/Parent 18988 0 R/B[4176 0 
R]/StructParents 6/Contents 27 0 R/Rotate 0/MediaBox[0 0 612 
792]/Resources 26 0 R/Type/Page>>
endobj


Okay, so that PDF was non-conforming, but it was good enough that I'd 
expect PDFBox to be able to parse it.  Let's take a look at the output and 
see what went wrong.
% we'll start at the trailer
trailer
<<
/Root 1 0 R
/ID [<78E9221F1CF4B2B411AC7654A2B830A0> 
<78E9221F1CF4B2B411AC7654A2B830A0>]
/Size 14095
>>

% then progress to the root
1 0 obj
<<
/Type /Catalog
/Version /1.4
/Pages 2 0 R
/Outlines 3 0 R
>>
endobj

Ah ha, we don't have /Names, which means we can't have any named 
destinations.  Now, think about why this might be.  What did we copy over 
when we made this new PDF?  Just the pages.  We didn't copy over the 
outline, nor any of the named destinations.  So I wouldn't say there's any 
bug in PDFBox here (at least not based on what I've seen thus far).  The 
reason it worked in the previous file was because it wasn't a named 
destination which was used, it was a page reference and a specific x,y 
value.

The reason I went through this long example is to show you how I figured 
out where the problem lies.  I hope that part was helpful.  I don't really 
have an answer on how to fix this, but I can at least show you why it's 
breaking.  I'm pretty sure you know more about named destinations than I 
do, so hopefully you can take this information and put it to good use.  I 
did just notice that PDFMergerUtility::appendDocument() handles the 
catalog Names.  You might be able to look there for an example. 
PDDocumentNameDictionary destNames = destCatalog.getNames();  I can't say 
whether or not this will have all the information you're looking for or 
not, but it should at least be a good first step.

Let me know if you have any other questions.

---- 
Thanks,
Adam





From:
"Hesham G." <he...@gmail.com>
To:
<us...@pdfbox.apache.org>
Date:
09/04/2010 01:49
Subject:
Re: getting and setting names of named destinations



Adam ,

Thanks a lot for your time and effort.

The PDF sample you have downloaded is a small sample that I used a 
splitter program to split part of my big PDF so you can download it 
easily. I have tested this small PDF now and you are right it worked fine 
... I think the splitter did that fix.

But when I tried the same code on the original big PDF it did not work. I 
tried PDFBox latest version 1.2.1 to test it. When I click on any of the 
bookmarks, nothing happens.
If you have time please test the same code on the original PDF, here : 
http://www.4shared.com/document/hEKeK6PJ/Java_Studio_Creator_IDE.html


Best regards ,
Hesham 

---------------------------------------------
Included message :

> Hesham,
> 
> The first thing I did was download the PDF and look at it.  That didn't 
> help much since everything is compressed, so I decompressed it using 
pdftk 
> so it's human readable.  Then I found the object which links to a 
specific 
> place in a page, I chose the "Classes" bookmark.
> 
> 53 0 obj 
> <<
> /First 54 0 R
> /Title (Classes)
> /Parent 49 0 R
> /Dest [29 0 R /XYZ 109 639 null]
> /Count 1
> /Next 51 0 R
> /Last 54 0 R
> /Prev 52 0 R
>>>
> 
> The destination is "29 0 R" which is a page, and the XYZ is also set.  I 

> had to look that one up in the spec and found it in section 12.3.2.2. 
This 
> is the left, top, and zoom.  So the point 109,639 will be in the top 
left 
> corner when clicking the link.  At this point I at least know how it 
> works.  As a final test, I searched the PDF for "G917701" and did not 
find 
> anything.
> 
> Then I ran you sample code on the uncompressed file.  Before even 
opening 
> it with Adobe, I traced from the trailer -> root -> catalog -> through 
the 
> bookmarks until I got to object 77, which was the "Classes" bookmark. It 

> looked correct, so I opened the file in Adobe Reader and it worked just 
> fine.  This confirms that there is not a problem in importPage() under 
all 
> circumstances (if at all).
> 
> I then ran that same code with the original, compressed PDF and the 
> "Classes" bookmark worked fine.  So I'm unable to duplicate your test 
> results.  For reference, here's the object from the output file when 
using 
> the exact file I downloaded from your link:
> 76 0 obj
> <<
> /Next 62 0 R
> /Parent 44 0 R
> /Dest [86 0 R /XYZ 109 639 null]
> /Title (Classes)
> /Prev 77 0 R
> /Count 1
> /Last 89 0 R
> /First 89 0 R
>>>
> 
> I do not have enough time to look into this any further and try to 
> determine how to set named destinations, however I'll do my best to try 
to 
> get you squared away with simple tests like this one.  If you're not 
> getting the same results as me with this simple test, it may be that 
> fixing this problem will also resolve other issues you're facing.
> 
> I'm using the latest code from SVN, which may be a difference between my 

> system and yours.  So take a look at the objects in your output PDF 
(using 
> a decent text editor) and see if anything is different.  Trace around 
and 
> see if the destination page is actually a page object, and if it is 
listed 
> in the /Pages section.  If everything looks like it's correct in the 
file, 
> but the bookmark still doesn't work, post your output file somewhere 
> online and link us to it like you did with the example file below.
> 
> As long as I can run a quick test in just a few minutes (like your 
example 
> here) and know exactly what to look for, I should be able to take a 
look. 
> It's just when the code gets long and complex that it'll be an issue. As 

> long as your reports are as short and concise as this one, I'm sure 
we'll 
> get it resolved quickly.
> 
> ---- 
> Thanks,
> Adam
> 
> 
> 
> 
> 
> From:
> Hesham Gneady <he...@gmail.com>
> To:
> users@pdfbox.apache.org
> Date:
> 09/02/2010 02:32
> Subject:
> Re: getting and setting names of named destinations
> 
> 
> 
> Kevin and Adam ,
> 
> I have made some tests and i am now sure of the problem ... The problem 
is
> not in the method setNamedDestination( "G917701" );
> The main problem is if i use importPage(...) to copy/paste some pdf 
pages,
> then copy their bookmarks. Here is a code sample where i copy a PDF 
having
> Named destinations bookmarks to another new PDF :
> 
> public void copyPDFWithNDBookmarks() {
> String inputpath = "C:\\inputPDF.pdf";  // Has bookmarks with named
> destinations.
> String ouputpath = "C:\\outputPDF.pdf";
> try {
> PDDocument inputPDFFile = PDDocument.load( inputpath );
> PDDocument outputPDFFile = new PDDocument();
> List<PDPage> inputPDFPages =
> inputPDFFile.getDocumentCatalog().getAllPages();  // Get all pages of 
this
> PDF.
> // Copy/Paste all PDF pages :
>        for( PDPage page: inputPDFPages )
>        outputPDFFile.importPage( page );
> 
> // Copy/Paste all bookmarks
> PDDocumentOutline pdfBookmarks =
> inputPDFFile.getDocumentCatalog().getDocumentOutline();
> outputPDFFile.getDocumentCatalog().setDocumentOutline( pdfBookmarks );
> 
> outputPDFFile.save( ouputpath );
> outputPDFFile.close();
> } catch (IOException e) {
> e.printStackTrace();
> } catch (COSVisitorException e) {
> e.printStackTrace();
> }
> }
> 
> You can try this PDF as an input PDF:
> 
http://www.4shared.com/document/XrPhJSCd/sample_pdf_having_bookmarks_wi.html

> 
> When you open the output PDF and click any bookmark ... Nothing will 
> happen
> !
> I think this is a problem in PDFBox importPage(...) method.
> 
> Adam ... Can you please check this out ?
> I have checked the mailing list, and i see many people asking about the
> Named destinations, but they mostly reach a dead end.
> 
> Best regards ,
> Hesham
> 
> 
> On Wed, Sep 1, 2010 at 6:13 PM, Kevin Brown <kb...@gmail.com> wrote:
> 
>> Hesham,
>>
>> I'm sorry to mislead you. I looked at my notes and it turns out I never
>> created them; I just edited them. So I a'm not sure I can help you. I 
am
>> very interested in this and will experiment with it next week.
>>
>> Has anyone out there been able to create named destinations using 
> pdfbox?
>>
>> Kevin
>>
>>
>> On Wed, Sep 1, 2010 at 10:04 AM, Hesham G. <he...@gmail.com> 
> wrote:
>>
>> > Strange ... I will try to dig in this, and I will be waiting your 
> reply
>> for
>> > more details if you can help.
>> > Happy trip ...
>> >
>> > Best regards ,
>> > Hesham
>> >
>> > ---------------------------------------------
>> > Included message :
>> >
>> > > No, I was able to get mine to work sorta... the named destinations 
> are
>> > > problematic tho. I am sorry, but I am going out of town for a week. 

> But
>> I
>> > > will post on this when I get back. Good luck.
>> > >
>> > > Kevin
>> > >
>> > >
>> > > On Wed, Sep 1, 2010 at 5:48 AM, Hesham G. <he...@gmail.com>
>> > wrote:
>> > >
>> > >> Kevin ,
>> > >>
>> > >> You said you were having problems setting a named destination. I 
> have
>> > tried
>> > >> to define a bookmark named destination but it didn't work.
>> > >> Here is my code :
>> > >> PDNamedDestination pn = new PDNamedDestination();
>> > >> pn.setNamedDestination( "G917701" );
>> > >> bookmark.setDestination( pn );
>> > >>
>> > >> When I open the PDF & click on that bookmark, nothing happens. I 
> have
>> a
>> > PDF
>> > >> editor that shows me the bookmark destinations ... So when I 
showed
>> the
>> > >> named destination for this bookmark, it was empty !
>> > >> Some how it was not set at all. Is this the problem you are facing 

> ?
>> > >>
>> > >> Best regards ,
>> > >> Hesham
>> > >
>> >
>>
> 
> 
> 
> -- 
> Thanks ,
> Hesham Gneady
> Software Developer
> 
> 
> 
> ?  Click here to submit conditions 
> 
> This email and any content within or attached hereto from  Sun West 
Mortgage Company, Inc.  is confidential and/or legally privileged. The 
information is intended only for the use of the individual or entity named 
on this email. If you are not the intended recipient, you are hereby 
notified that any disclosure, copying, distribution or the taking of any 
action in reliance on the contents of this email information is strictly 
prohibited, and that the documents should be returned to this office 
immediately by email. Receipt by anyone other than the intended recipient 
is not a waiver of any privilege. Please do not include your social 
security number, account number, or any other personal or financial 
information in the content of the email. Should you have any questions, 
please call  (800) 453 7884.   =


?  Click here to submit conditions  

This email and any content within or attached hereto from  Sun West Mortgage Company, Inc.  is confidential and/or legally privileged. The information is intended only for the use of the individual or entity named on this email. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution or the taking of any action in reliance on the contents of this email information is strictly prohibited, and that the documents should be returned to this office immediately by email. Receipt by anyone other than the intended recipient is not a waiver of any privilege. Please do not include your social security number, account number, or any other personal or financial information in the content of the email. Should you have any questions, please call  (800) 453 7884.   

Re: getting and setting names of named destinations

Posted by "Hesham G." <he...@gmail.com>.
Adam ,

Thanks a lot for your time and effort.

The PDF sample you have downloaded is a small sample that I used a splitter program to split part of my big PDF so you can download it easily. I have tested this small PDF now and you are right it worked fine ... I think the splitter did that fix.

But when I tried the same code on the original big PDF it did not work. I tried PDFBox latest version 1.2.1 to test it. When I click on any of the bookmarks, nothing happens.
If you have time please test the same code on the original PDF, here : 
http://www.4shared.com/document/hEKeK6PJ/Java_Studio_Creator_IDE.html


Best regards ,
Hesham 

---------------------------------------------
Included message :

> Hesham,
> 
> The first thing I did was download the PDF and look at it.  That didn't 
> help much since everything is compressed, so I decompressed it using pdftk 
> so it's human readable.  Then I found the object which links to a specific 
> place in a page, I chose the "Classes" bookmark.
> 
> 53 0 obj 
> <<
> /First 54 0 R
> /Title (Classes)
> /Parent 49 0 R
> /Dest [29 0 R /XYZ 109 639 null]
> /Count 1
> /Next 51 0 R
> /Last 54 0 R
> /Prev 52 0 R
>>>
> 
> The destination is "29 0 R" which is a page, and the XYZ is also set.  I 
> had to look that one up in the spec and found it in section 12.3.2.2. This 
> is the left, top, and zoom.  So the point 109,639 will be in the top left 
> corner when clicking the link.  At this point I at least know how it 
> works.  As a final test, I searched the PDF for "G917701" and did not find 
> anything.
> 
> Then I ran you sample code on the uncompressed file.  Before even opening 
> it with Adobe, I traced from the trailer -> root -> catalog -> through the 
> bookmarks until I got to object 77, which was the "Classes" bookmark.  It 
> looked correct, so I opened the file in Adobe Reader and it worked just 
> fine.  This confirms that there is not a problem in importPage() under all 
> circumstances (if at all).
> 
> I then ran that same code with the original, compressed PDF and the 
> "Classes" bookmark worked fine.  So I'm unable to duplicate your test 
> results.  For reference, here's the object from the output file when using 
> the exact file I downloaded from your link:
> 76 0 obj
> <<
> /Next 62 0 R
> /Parent 44 0 R
> /Dest [86 0 R /XYZ 109 639 null]
> /Title (Classes)
> /Prev 77 0 R
> /Count 1
> /Last 89 0 R
> /First 89 0 R
>>>
> 
> I do not have enough time to look into this any further and try to 
> determine how to set named destinations, however I'll do my best to try to 
> get you squared away with simple tests like this one.  If you're not 
> getting the same results as me with this simple test, it may be that 
> fixing this problem will also resolve other issues you're facing.
> 
> I'm using the latest code from SVN, which may be a difference between my 
> system and yours.  So take a look at the objects in your output PDF (using 
> a decent text editor) and see if anything is different.  Trace around and 
> see if the destination page is actually a page object, and if it is listed 
> in the /Pages section.  If everything looks like it's correct in the file, 
> but the bookmark still doesn't work, post your output file somewhere 
> online and link us to it like you did with the example file below.
> 
> As long as I can run a quick test in just a few minutes (like your example 
> here) and know exactly what to look for, I should be able to take a look. 
> It's just when the code gets long and complex that it'll be an issue.  As 
> long as your reports are as short and concise as this one, I'm sure we'll 
> get it resolved quickly.
> 
> ---- 
> Thanks,
> Adam
> 
> 
> 
> 
> 
> From:
> Hesham Gneady <he...@gmail.com>
> To:
> users@pdfbox.apache.org
> Date:
> 09/02/2010 02:32
> Subject:
> Re: getting and setting names of named destinations
> 
> 
> 
> Kevin and Adam ,
> 
> I have made some tests and i am now sure of the problem ... The problem is
> not in the method setNamedDestination( "G917701" );
> The main problem is if i use importPage(...) to copy/paste some pdf pages,
> then copy their bookmarks. Here is a code sample where i copy a PDF having
> Named destinations bookmarks to another new PDF :
> 
> public void copyPDFWithNDBookmarks() {
> String inputpath = "C:\\inputPDF.pdf";  // Has bookmarks with named
> destinations.
> String ouputpath = "C:\\outputPDF.pdf";
> try {
> PDDocument inputPDFFile = PDDocument.load( inputpath );
> PDDocument outputPDFFile = new PDDocument();
> List<PDPage> inputPDFPages =
> inputPDFFile.getDocumentCatalog().getAllPages();  // Get all pages of this
> PDF.
> // Copy/Paste all PDF pages :
>        for( PDPage page: inputPDFPages )
>        outputPDFFile.importPage( page );
> 
> // Copy/Paste all bookmarks
> PDDocumentOutline pdfBookmarks =
> inputPDFFile.getDocumentCatalog().getDocumentOutline();
> outputPDFFile.getDocumentCatalog().setDocumentOutline( pdfBookmarks );
> 
> outputPDFFile.save( ouputpath );
> outputPDFFile.close();
> } catch (IOException e) {
> e.printStackTrace();
> } catch (COSVisitorException e) {
> e.printStackTrace();
> }
> }
> 
> You can try this PDF as an input PDF:
> http://www.4shared.com/document/XrPhJSCd/sample_pdf_having_bookmarks_wi.html
> 
> When you open the output PDF and click any bookmark ... Nothing will 
> happen
> !
> I think this is a problem in PDFBox importPage(...) method.
> 
> Adam ... Can you please check this out ?
> I have checked the mailing list, and i see many people asking about the
> Named destinations, but they mostly reach a dead end.
> 
> Best regards ,
> Hesham
> 
> 
> On Wed, Sep 1, 2010 at 6:13 PM, Kevin Brown <kb...@gmail.com> wrote:
> 
>> Hesham,
>>
>> I'm sorry to mislead you. I looked at my notes and it turns out I never
>> created them; I just edited them. So I a'm not sure I can help you. I am
>> very interested in this and will experiment with it next week.
>>
>> Has anyone out there been able to create named destinations using 
> pdfbox?
>>
>> Kevin
>>
>>
>> On Wed, Sep 1, 2010 at 10:04 AM, Hesham G. <he...@gmail.com> 
> wrote:
>>
>> > Strange ... I will try to dig in this, and I will be waiting your 
> reply
>> for
>> > more details if you can help.
>> > Happy trip ...
>> >
>> > Best regards ,
>> > Hesham
>> >
>> > ---------------------------------------------
>> > Included message :
>> >
>> > > No, I was able to get mine to work sorta... the named destinations 
> are
>> > > problematic tho. I am sorry, but I am going out of town for a week. 
> But
>> I
>> > > will post on this when I get back. Good luck.
>> > >
>> > > Kevin
>> > >
>> > >
>> > > On Wed, Sep 1, 2010 at 5:48 AM, Hesham G. <he...@gmail.com>
>> > wrote:
>> > >
>> > >> Kevin ,
>> > >>
>> > >> You said you were having problems setting a named destination. I 
> have
>> > tried
>> > >> to define a bookmark named destination but it didn't work.
>> > >> Here is my code :
>> > >> PDNamedDestination pn = new PDNamedDestination();
>> > >> pn.setNamedDestination( "G917701" );
>> > >> bookmark.setDestination( pn );
>> > >>
>> > >> When I open the PDF & click on that bookmark, nothing happens. I 
> have
>> a
>> > PDF
>> > >> editor that shows me the bookmark destinations ... So when I showed
>> the
>> > >> named destination for this bookmark, it was empty !
>> > >> Some how it was not set at all. Is this the problem you are facing 
> ?
>> > >>
>> > >> Best regards ,
>> > >> Hesham
>> > >
>> >
>>
> 
> 
> 
> -- 
> Thanks ,
> Hesham Gneady
> Software Developer
> 
> 
> 
> ?  Click here to submit conditions  
> 
> This email and any content within or attached hereto from  Sun West Mortgage Company, Inc.  is confidential and/or legally privileged. The information is intended only for the use of the individual or entity named on this email. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution or the taking of any action in reliance on the contents of this email information is strictly prohibited, and that the documents should be returned to this office immediately by email. Receipt by anyone other than the intended recipient is not a waiver of any privilege. Please do not include your social security number, account number, or any other personal or financial information in the content of the email. Should you have any questions, please call  (800) 453 7884.   =

Re: getting and setting names of named destinations

Posted by Ad...@swmc.com.
Hesham,

The first thing I did was download the PDF and look at it.  That didn't 
help much since everything is compressed, so I decompressed it using pdftk 
so it's human readable.  Then I found the object which links to a specific 
place in a page, I chose the "Classes" bookmark.

53 0 obj 
<<
/First 54 0 R
/Title (Classes)
/Parent 49 0 R
/Dest [29 0 R /XYZ 109 639 null]
/Count 1
/Next 51 0 R
/Last 54 0 R
/Prev 52 0 R
>>

The destination is "29 0 R" which is a page, and the XYZ is also set.  I 
had to look that one up in the spec and found it in section 12.3.2.2. This 
is the left, top, and zoom.  So the point 109,639 will be in the top left 
corner when clicking the link.  At this point I at least know how it 
works.  As a final test, I searched the PDF for "G917701" and did not find 
anything.

Then I ran you sample code on the uncompressed file.  Before even opening 
it with Adobe, I traced from the trailer -> root -> catalog -> through the 
bookmarks until I got to object 77, which was the "Classes" bookmark.  It 
looked correct, so I opened the file in Adobe Reader and it worked just 
fine.  This confirms that there is not a problem in importPage() under all 
circumstances (if at all).

I then ran that same code with the original, compressed PDF and the 
"Classes" bookmark worked fine.  So I'm unable to duplicate your test 
results.  For reference, here's the object from the output file when using 
the exact file I downloaded from your link:
76 0 obj
<<
/Next 62 0 R
/Parent 44 0 R
/Dest [86 0 R /XYZ 109 639 null]
/Title (Classes)
/Prev 77 0 R
/Count 1
/Last 89 0 R
/First 89 0 R
>>

I do not have enough time to look into this any further and try to 
determine how to set named destinations, however I'll do my best to try to 
get you squared away with simple tests like this one.  If you're not 
getting the same results as me with this simple test, it may be that 
fixing this problem will also resolve other issues you're facing.

I'm using the latest code from SVN, which may be a difference between my 
system and yours.  So take a look at the objects in your output PDF (using 
a decent text editor) and see if anything is different.  Trace around and 
see if the destination page is actually a page object, and if it is listed 
in the /Pages section.  If everything looks like it's correct in the file, 
but the bookmark still doesn't work, post your output file somewhere 
online and link us to it like you did with the example file below.

As long as I can run a quick test in just a few minutes (like your example 
here) and know exactly what to look for, I should be able to take a look. 
It's just when the code gets long and complex that it'll be an issue.  As 
long as your reports are as short and concise as this one, I'm sure we'll 
get it resolved quickly.

---- 
Thanks,
Adam





From:
Hesham Gneady <he...@gmail.com>
To:
users@pdfbox.apache.org
Date:
09/02/2010 02:32
Subject:
Re: getting and setting names of named destinations



Kevin and Adam ,

I have made some tests and i am now sure of the problem ... The problem is
not in the method setNamedDestination( "G917701" );
The main problem is if i use importPage(...) to copy/paste some pdf pages,
then copy their bookmarks. Here is a code sample where i copy a PDF having
Named destinations bookmarks to another new PDF :

public void copyPDFWithNDBookmarks() {
String inputpath = "C:\\inputPDF.pdf";  // Has bookmarks with named
destinations.
String ouputpath = "C:\\outputPDF.pdf";
 try {
PDDocument inputPDFFile = PDDocument.load( inputpath );
PDDocument outputPDFFile = new PDDocument();
List<PDPage> inputPDFPages =
inputPDFFile.getDocumentCatalog().getAllPages();  // Get all pages of this
PDF.
 // Copy/Paste all PDF pages :
        for( PDPage page: inputPDFPages )
        outputPDFFile.importPage( page );

// Copy/Paste all bookmarks
PDDocumentOutline pdfBookmarks =
inputPDFFile.getDocumentCatalog().getDocumentOutline();
outputPDFFile.getDocumentCatalog().setDocumentOutline( pdfBookmarks );

outputPDFFile.save( ouputpath );
outputPDFFile.close();
} catch (IOException e) {
e.printStackTrace();
} catch (COSVisitorException e) {
e.printStackTrace();
}
}

You can try this PDF as an input PDF:
http://www.4shared.com/document/XrPhJSCd/sample_pdf_having_bookmarks_wi.html

When you open the output PDF and click any bookmark ... Nothing will 
happen
!
I think this is a problem in PDFBox importPage(...) method.

Adam ... Can you please check this out ?
I have checked the mailing list, and i see many people asking about the
Named destinations, but they mostly reach a dead end.

Best regards ,
Hesham


On Wed, Sep 1, 2010 at 6:13 PM, Kevin Brown <kb...@gmail.com> wrote:

> Hesham,
>
> I'm sorry to mislead you. I looked at my notes and it turns out I never
> created them; I just edited them. So I a'm not sure I can help you. I am
> very interested in this and will experiment with it next week.
>
> Has anyone out there been able to create named destinations using 
pdfbox?
>
> Kevin
>
>
> On Wed, Sep 1, 2010 at 10:04 AM, Hesham G. <he...@gmail.com> 
wrote:
>
> > Strange ... I will try to dig in this, and I will be waiting your 
reply
> for
> > more details if you can help.
> > Happy trip ...
> >
> > Best regards ,
> > Hesham
> >
> > ---------------------------------------------
> > Included message :
> >
> > > No, I was able to get mine to work sorta... the named destinations 
are
> > > problematic tho. I am sorry, but I am going out of town for a week. 
But
> I
> > > will post on this when I get back. Good luck.
> > >
> > > Kevin
> > >
> > >
> > > On Wed, Sep 1, 2010 at 5:48 AM, Hesham G. <he...@gmail.com>
> > wrote:
> > >
> > >> Kevin ,
> > >>
> > >> You said you were having problems setting a named destination. I 
have
> > tried
> > >> to define a bookmark named destination but it didn't work.
> > >> Here is my code :
> > >> PDNamedDestination pn = new PDNamedDestination();
> > >> pn.setNamedDestination( "G917701" );
> > >> bookmark.setDestination( pn );
> > >>
> > >> When I open the PDF & click on that bookmark, nothing happens. I 
have
> a
> > PDF
> > >> editor that shows me the bookmark destinations ... So when I showed
> the
> > >> named destination for this bookmark, it was empty !
> > >> Some how it was not set at all. Is this the problem you are facing 
?
> > >>
> > >> Best regards ,
> > >> Hesham
> > >
> >
>



-- 
Thanks ,
Hesham Gneady
Software Developer



?  Click here to submit conditions  

This email and any content within or attached hereto from  Sun West Mortgage Company, Inc.  is confidential and/or legally privileged. The information is intended only for the use of the individual or entity named on this email. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution or the taking of any action in reliance on the contents of this email information is strictly prohibited, and that the documents should be returned to this office immediately by email. Receipt by anyone other than the intended recipient is not a waiver of any privilege. Please do not include your social security number, account number, or any other personal or financial information in the content of the email. Should you have any questions, please call  (800) 453 7884.   

Re: getting and setting names of named destinations

Posted by Hesham Gneady <he...@gmail.com>.
Kevin and Adam ,

I have made some tests and i am now sure of the problem ... The problem is
not in the method setNamedDestination( "G917701" );
The main problem is if i use importPage(...) to copy/paste some pdf pages,
then copy their bookmarks. Here is a code sample where i copy a PDF having
Named destinations bookmarks to another new PDF :

public void copyPDFWithNDBookmarks() {
String inputpath = "C:\\inputPDF.pdf";  // Has bookmarks with named
destinations.
String ouputpath = "C:\\outputPDF.pdf";
 try {
PDDocument inputPDFFile = PDDocument.load( inputpath );
PDDocument outputPDFFile = new PDDocument();
List<PDPage> inputPDFPages =
inputPDFFile.getDocumentCatalog().getAllPages();  // Get all pages of this
PDF.
 // Copy/Paste all PDF pages :
        for( PDPage page: inputPDFPages )
        outputPDFFile.importPage( page );

// Copy/Paste all bookmarks
PDDocumentOutline pdfBookmarks =
inputPDFFile.getDocumentCatalog().getDocumentOutline();
outputPDFFile.getDocumentCatalog().setDocumentOutline( pdfBookmarks );

outputPDFFile.save( ouputpath );
outputPDFFile.close();
} catch (IOException e) {
e.printStackTrace();
} catch (COSVisitorException e) {
e.printStackTrace();
}
}

You can try this PDF as an input PDF:
http://www.4shared.com/document/XrPhJSCd/sample_pdf_having_bookmarks_wi.html
When you open the output PDF and click any bookmark ... Nothing will happen
!
I think this is a problem in PDFBox importPage(...) method.

Adam ... Can you please check this out ?
I have checked the mailing list, and i see many people asking about the
Named destinations, but they mostly reach a dead end.

Best regards ,
Hesham


On Wed, Sep 1, 2010 at 6:13 PM, Kevin Brown <kb...@gmail.com> wrote:

> Hesham,
>
> I'm sorry to mislead you. I looked at my notes and it turns out I never
> created them; I just edited them. So I a'm not sure I can help you. I am
> very interested in this and will experiment with it next week.
>
> Has anyone out there been able to create named destinations using pdfbox?
>
> Kevin
>
>
> On Wed, Sep 1, 2010 at 10:04 AM, Hesham G. <he...@gmail.com> wrote:
>
> > Strange ... I will try to dig in this, and I will be waiting your reply
> for
> > more details if you can help.
> > Happy trip ...
> >
> > Best regards ,
> > Hesham
> >
> > ---------------------------------------------
> > Included message :
> >
> > > No, I was able to get mine to work sorta... the named destinations are
> > > problematic tho. I am sorry, but I am going out of town for a week. But
> I
> > > will post on this when I get back. Good luck.
> > >
> > > Kevin
> > >
> > >
> > > On Wed, Sep 1, 2010 at 5:48 AM, Hesham G. <he...@gmail.com>
> > wrote:
> > >
> > >> Kevin ,
> > >>
> > >> You said you were having problems setting a named destination. I have
> > tried
> > >> to define a bookmark named destination but it didn't work.
> > >> Here is my code :
> > >> PDNamedDestination pn = new PDNamedDestination();
> > >> pn.setNamedDestination( "G917701" );
> > >> bookmark.setDestination( pn );
> > >>
> > >> When I open the PDF & click on that bookmark, nothing happens. I have
> a
> > PDF
> > >> editor that shows me the bookmark destinations ... So when I showed
> the
> > >> named destination for this bookmark, it was empty !
> > >> Some how it was not set at all. Is this the problem you are facing ?
> > >>
> > >> Best regards ,
> > >> Hesham
> > >
> >
>



-- 
Thanks ,
Hesham Gneady
Software Developer

Re: getting and setting names of named destinations

Posted by Kevin Brown <kb...@gmail.com>.
Hesham,

I'm sorry to mislead you. I looked at my notes and it turns out I never
created them; I just edited them. So I a'm not sure I can help you. I am
very interested in this and will experiment with it next week.

Has anyone out there been able to create named destinations using pdfbox?

Kevin


On Wed, Sep 1, 2010 at 10:04 AM, Hesham G. <he...@gmail.com> wrote:

> Strange ... I will try to dig in this, and I will be waiting your reply for
> more details if you can help.
> Happy trip ...
>
> Best regards ,
> Hesham
>
> ---------------------------------------------
> Included message :
>
> > No, I was able to get mine to work sorta... the named destinations are
> > problematic tho. I am sorry, but I am going out of town for a week. But I
> > will post on this when I get back. Good luck.
> >
> > Kevin
> >
> >
> > On Wed, Sep 1, 2010 at 5:48 AM, Hesham G. <he...@gmail.com>
> wrote:
> >
> >> Kevin ,
> >>
> >> You said you were having problems setting a named destination. I have
> tried
> >> to define a bookmark named destination but it didn't work.
> >> Here is my code :
> >> PDNamedDestination pn = new PDNamedDestination();
> >> pn.setNamedDestination( "G917701" );
> >> bookmark.setDestination( pn );
> >>
> >> When I open the PDF & click on that bookmark, nothing happens. I have a
> PDF
> >> editor that shows me the bookmark destinations ... So when I showed the
> >> named destination for this bookmark, it was empty !
> >> Some how it was not set at all. Is this the problem you are facing ?
> >>
> >> Best regards ,
> >> Hesham
> >
>

Re: getting and setting names of named destinations

Posted by "Hesham G." <he...@gmail.com>.
Strange ... I will try to dig in this, and I will be waiting your reply for more details if you can help.
Happy trip ...

Best regards ,
Hesham

---------------------------------------------
Included message :

> No, I was able to get mine to work sorta... the named destinations are
> problematic tho. I am sorry, but I am going out of town for a week. But I
> will post on this when I get back. Good luck.
> 
> Kevin
> 
> 
> On Wed, Sep 1, 2010 at 5:48 AM, Hesham G. <he...@gmail.com> wrote:
> 
>> Kevin ,
>>
>> You said you were having problems setting a named destination. I have tried
>> to define a bookmark named destination but it didn't work.
>> Here is my code :
>> PDNamedDestination pn = new PDNamedDestination();
>> pn.setNamedDestination( "G917701" );
>> bookmark.setDestination( pn );
>>
>> When I open the PDF & click on that bookmark, nothing happens. I have a PDF
>> editor that shows me the bookmark destinations ... So when I showed the
>> named destination for this bookmark, it was empty !
>> Some how it was not set at all. Is this the problem you are facing ?
>>
>> Best regards ,
>> Hesham
>

Re: getting and setting names of named destinations

Posted by Kevin Brown <kb...@gmail.com>.
No, I was able to get mine to work sorta... the named destinations are
problematic tho. I am sorry, but I am going out of town for a week. But I
will post on this when I get back. Good luck.

Kevin


On Wed, Sep 1, 2010 at 5:48 AM, Hesham G. <he...@gmail.com> wrote:

> Kevin ,
>
> You said you were having problems setting a named destination. I have tried
> to define a bookmark named destination but it didn't work.
> Here is my code :
> PDNamedDestination pn = new PDNamedDestination();
> pn.setNamedDestination( "G917701" );
> bookmark.setDestination( pn );
>
> When I open the PDF & click on that bookmark, nothing happens. I have a PDF
> editor that shows me the bookmark destinations ... So when I showed the
> named destination for this bookmark, it was empty !
> Some how it was not set at all. Is this the problem you are facing ?
>
> Best regards ,
> Hesham

Re: getting and setting names of named destinations

Posted by "Hesham G." <he...@gmail.com>.
Kevin ,

You said you were having problems setting a named destination. I have tried to define a bookmark named destination but it didn't work.
Here is my code :
PDNamedDestination pn = new PDNamedDestination();
pn.setNamedDestination( "G917701" );
bookmark.setDestination( pn );

When I open the PDF & click on that bookmark, nothing happens. I have a PDF editor that shows me the bookmark destinations ... So when I showed the named destination for this bookmark, it was empty !
Some how it was not set at all. Is this the problem you are facing ?

Best regards ,
Hesham

Re: getting and setting names of named destinations

Posted by Kevin Brown <kb...@gmail.com>.
Thanks a lot. I was able to get them as well. However, I still run into some
problems when I set them. I've decided to use a different means to set them
for my work, so I don't need PDFBox for that any more. However it would be
nice if it worked a little better (IMHO).



On Tue, Aug 31, 2010 at 8:46 AM, Hesham Gneady <he...@gmail.com>wrote:

> Kevin ,
>
> I have been investigating the Named destinations for bookmarks, and i
> remembered your problem. Please try this example to get the names of the
> destinations ... I hope it's right :
>
> try {
> PDNamedDestination pn = (PDNamedDestination)bookmark.getDestination();  //
> The bookmark = A PDOutlineItem object.
> if( pn != null ) System.out.println("Page: " + (pageNumber + 1) + " - Named
> dest: " + pn.getNamedDestination());
> } catch (Exception e) {
> e.printStackTrace();
> }
>
> When i executed this on one of my PDFs here is the result :
> Page: 2 - Named dest: G917701
> Page: 3 - Named dest: G976457
> Page: 5 - Named dest: G983176
> .....
>
> Best regards ,
> Hesham
>

Re: getting and setting names of named destinations

Posted by Hesham Gneady <he...@gmail.com>.
Kevin ,

I have been investigating the Named destinations for bookmarks, and i
remembered your problem. Please try this example to get the names of the
destinations ... I hope it's right :

try {
PDNamedDestination pn = (PDNamedDestination)bookmark.getDestination();  //
The bookmark = A PDOutlineItem object.
if( pn != null ) System.out.println("Page: " + (pageNumber + 1) + " - Named
dest: " + pn.getNamedDestination());
} catch (Exception e) {
e.printStackTrace();
}

When i executed this on one of my PDFs here is the result :
Page: 2 - Named dest: G917701
Page: 3 - Named dest: G976457
Page: 5 - Named dest: G983176
.....

Best regards ,
Hesham

Re: getting and setting names of named destinations

Posted by Kevin Brown <kb...@gmail.com>.
I've figured this out. Basically you get a Map from getNames() and can fix
the destination names (keys), then use setNames(). However this seems to
break the destinations in a way that I do not understand. I will keep
plugging away and will post code samples when I have it worked out.

Anyone else interested in this, please chime in with your thoughts and
experience.



On Wed, Jun 30, 2010 at 11:03 AM, Kevin Brown <kb...@gmail.com> wrote:

> Ok, sort of pigybacking off the previous discussions... I was able to get
> PDFBox to allow me to get the page numbers of named dests, and even to alter
> the zoom factor for each one. However, I cannot get and/or set the names
> themselves (the actual names of the named destinations). Anyone got any
> ideas? Would this be something that could be added into a future release?
>
> Thanks,
>
> Kevin
>
>
> On Sun, Jun 20, 2010 at 1:13 AM, Hesham G. <he...@gmail.com> wrote:
>
>> Thank you Adam for the explanation, and thanks Kevin for the code.
>> As Adam says it's high level of precision ... But Kevin did a nice work
>> here.
>>
>> Best regards ,
>> Hesham
>>
>>
>> ---------------------------------------------
>> Included message :
>>
>>
>> > One thing I haven't been able to get is the actual name of the named
>> > destinations. You would think there would be something like getName()
>> > setName() methods. I'll keep poking around.
>> >
>> >
>> > On Fri, Jun 18, 2010 at 1:23 PM, Kevin Brown <kb...@gmail.com> wrote:
>> >
>> >> This aint pretty. It's just a proof of concept written by a Java
>> hacking
>> >> fool. I'm going to refactor if I get approval. :)
>> >>
>> >> Basically you need to start with this (document is a PDDocument):
>> >>
>> >>
>> >>     PDDocumentCatalog log = document.getDocumentCatalog();
>> >>
>> >>         PDDocumentNameDictionary dic = log.getNames();
>> >>         PDDestinationNameTreeNode dests = dic.getDests();
>> >>
>> >> Okay, so the destinations will be available via the getNames() method
>> of
>> >> dests, if they exist at that level. If they do not, you need to bore
>> down by
>> >> using the getKids() method, and check those items for names. If those
>> don't
>> >> work, bore down, etc. Here I print out all the named destinations, and
>> >> change the zoom property, for a particular type of  PDF; you may need
>> to
>> >> land at a different level of PDDestinationNameTreeNode.
>> >>
>> >> The PDPageXYZDestination class is the thing to keep an eye on.
>> >>
>> >>     private static boolean hasDests(PDDestinationNameTreeNode dests)
>> throws
>> >> IOException {
>> >>         if (dests.getNames() == null) {
>> >>             List kids = dests.getKids();
>> >>             List<PDNameTreeNode> destList = kids;
>> >>             System.out.println("No. of kids: " + destList.size());
>> >>             boolean val = false;
>> >>             for (PDNameTreeNode dest2 : destList) {
>> >>                 System.out.println("in for");
>> >>                 Map<?, ?> destList2 = dest2.getNames();
>> >>                 // System.out.println("getnames... " +
>> dest2.getNames());
>> >>
>> >>                 if (destList2 != null) {
>> >>                     System.out.println("we have some dests now...");
>> >>
>> >>                     Collection<PDPageXYZDestination> values =
>> >> (Collection<PDPageXYZDestination>) destList2.values();
>> >>                     Collection<PDPageXYZDestination> c = values;
>> >>                     System.out.println(c.size());
>> >>                     for (PDPageXYZDestination destNode : c) {
>> >>                         System.out.println(destNode.toString());
>> >>
>> >>                         System.out.println("tostring: " +
>> >> destNode.toString());
>> >>                         System.out.println("getleft: " +
>> >> destNode.getLeft());
>> >>                         System.out.println("getpagenumber" +
>> >> destNode.getPageNumber());
>> >>                         System.out.println("gettop: " +
>> destNode.getTop());
>> >>                         System.out.println("getzoom: " +
>> >> destNode.getZoom());
>> >>                         System.out.println("getpagenumber: " +
>> >> destNode.getPage());
>> >>                         System.out.println("getcosarray: " +
>> >> destNode.getCOSArray());
>> >>                         System.out.println("find page number: " +
>> >> destNode.findPageNumber());
>> >>                         System.out.println("getcosobject: " +
>> >> destNode.getCOSObject());
>> >>
>> >>
>> >> System.out.println("********************************************");
>> >>                         destNode.setZoom(-1);
>> >>                         val = true;
>> >>                     }
>> >>
>> >>                     System.out.println("next in for...");
>> >>                 } else {
>> >>
>> >>                     System.out.println("no names!");
>> >>                 }
>> >>
>> >>             }
>> >>             System.out.println("returning ... " + val);
>> >>             return val;
>> >>         } else {
>> >>             System.out.println("returning false...");
>> >>             return false;
>> >>
>> >>         }
>> >>     }
>> >>
>> >>
>> >> On Fri, Jun 18, 2010 at 12:09 PM, <Ad...@swmc.com> wrote:
>> >>
>> >>> Hesham,
>> >>>        A named destination is a specific type of node in the document
>> >>> outline (aka a specific type of bookmark).  A "normal" bookmark will
>> point
>> >>> to a page (via the page's object ID and revision) while a named
>> >>> destination will point to some name.  Then that needs to be resolved
>> >>> (somehow?) to the specific object that it points to.  The object could
>> be
>> >>> a page, an image, a paragraph, word, or anything else you'll find in a
>> >>> PDF.  The main difference is that you can jump to specific point in a
>> page
>> >>> (e.g. page 3 halfway down where a specific paragraph begins) instead
>> of
>> >>> just pointing to the page.  I've never needed this level of precision
>> and
>> >>> references to pages are simpler and more common (and slightly more
>> >>> efficient since it points directly to a page instead of pointing to a
>> >>> pointer to an object), so I have not yet used named destinations.  I
>> hope
>> >>> this helps explain the differences and why one would be chosen over
>> the
>> >>> other.
>> >>>
>> >>> Kevin,
>> >>> I too am interested in how you did this, as I expect I'll have to
>> cross
>> >>> this bridge at some point.
>> >>>
>> >>> ----
>> >>> Thanks,
>> >>> Adam
>> >>>
>> >>>
>> >>>
>> >>>
>> >>>
>> >>> From:
>> >>> "Hesham G." <he...@gmail.com>
>> >>> To:
>> >>> <us...@pdfbox.apache.org>
>> >>> Date:
>> >>> 06/17/2010 20:14
>> >>> Subject:
>> >>> Re: getting page numbers of named destinations
>> >>>
>> >>>
>> >>>
>> >>> Kevin ,
>> >>>
>> >>> I have been watching this post out, and I don't seem to understand yet
>> >>> what is the difference between "Named destinations" and "bookmarks"  ?
>> >>> And I hope if you could share your code with us for how you have got
>> it.
>> >>>
>> >>>
>> >>> Best regards ,
>> >>> Hesham
>> >>>
>> >>>
>> >>> ---------------------------------------------
>> >>> Included message :
>> >>>
>> >>> > Thank you SO MUCH, Adam. With your advice, and some tinkering with
>> >>> PDFBox, I
>> >>> > was able to get at and manipulate the named destinations.
>> >>> >
>> >>> > On Tue, Jun 1, 2010 at 3:23 PM, <Ad...@swmc.com> wrote:
>> >>> >
>> >>> >> Kevin,
>> >>> >>
>> >>> >> Section 7.7.2 of the PDF Spec (I'm referencing version 1.7) goes
>> over
>> >>> the
>> >>> >> Document catalog and table 20 points you to section 12.3.2.3 for
>> "Named
>> >>> >> Destinations").  Section 12.3.2.3 explains that "the correspondence
>> >>> >> between name objects and destinations shall be defined by the Dests
>> >>> entry
>> >>> >> in the document catalogue (see 7.7.2, "Document Catalog")."  So,
>> per
>> >>> the
>> >>> >> spec, the answer lies in the document catalog.
>> >>> >>
>> >>> >> Table 28 defines what entries are allowed in the catalog
>> dictionary.
>> >>> The
>> >>> >> "Document Outline" (i.e. key: "Outlines"), which are also known as
>> >>> >> bookmarks, are what you are looping through in your code.  So
>> that's
>> >>> why
>> >>> >> you're getting bookmarks and not named destinations.  You don't
>> want
>> >>> >> document.getDocumentCatalog().getDocumentOutline() but you do want
>> >>> >> document.getDocumentCatalog().
>> >>> >>
>> >>> >> Like I said before, I haven't actually dealt with named
>> destinations,
>> >>> nor
>> >>> >> have I even seen a document which uses them, so I don't know how
>> the
>> >>> >> "Dests" key works.  However, it should be pretty easy to figure if
>> you
>> >>> >> take a look at a PDF in vi, Notepad++, or any other quality editor.
>> >>> Once
>> >>> >> you know what you're looking for, it's just a matter of looking at
>> >>> things
>> >>> >> in PDDocumentCatalog to find it.
>> >>> >>
>> >>> >> ----
>> >>> >> Thanks,
>> >>> >> Adam
>> >>> >>
>> >>> >>
>> >>> >>
>> >>> >>
>> >>> >>
>> >>> >> From:
>> >>> >> Kevin Brown <kb...@gmail.com>
>> >>> >> To:
>> >>> >> users@pdfbox.apache.org
>> >>> >> Date:
>> >>> >> 05/25/2010 11:11
>> >>> >> Subject:
>> >>> >> Re: getting page numbers of named destinations
>> >>> >>
>> >>> >>
>> >>> >>
>> >>> >> Thanks much! I'm trying this but it seems to pull in bookmarks, not
>> >>> named
>> >>> >> destinations. Am I missing something?
>> >>> >>
>> >>> >>
>> >>> >> On Sat, May 22, 2010 at 11:15 AM, Andreas Lehmkuehler
>> >>> >> <an...@lehmi.de>wrote:
>> >>> >>
>> >>> >> > Hi
>> >>> >> >
>> >>> >> > Kevin Brown schrieb:
>> >>> >> >
>> >>> >> >  I can't seem to get this done with pdfbox. There doesn't seem to
>> be
>> >>> a
>> >>> >> way
>> >>> >> >> to
>> >>> >> >> get the page number from the context of the named destination.
>> Am I
>> >>> >> wrong?
>> >>> >> >> Anyone got any sample code for working with named destinations?
>> >>> >> >>
>> >>> >> > If you have a look at the mentioned example you find some code
>> like
>> >>> >> this:
>> >>> >> >
>> >>> >> > PDDocumentOutline
>> >>> >> > bookmarks=document.getDocumentCatalog().getDocumentOutline();
>> >>> >> > PDOutlineItem item = bookmarks.getFirstChild().getNextSibling();
>> >>> >> >
>> >>> >> > And the PDOutlineItem class provides a method to get the
>> >>> corresponding
>> >>> >> > page:
>> >>> >> >
>> >>> >> > /**
>> >>> >> >  * This method will attempt to find the page in this PDF document
>> >>> that
>> >>> >> this
>> >>> >> > outline points to.
>> >>> >> >  * If the outline does not point to anything then this method
>> will
>> >>> >> return
>> >>> >> > null.  If the outline
>> >>> >> >  * is an action that is not a GoTo action then this methods will
>> >>> throw
>> >>> >> the
>> >>> >> > OutlineNotLocationException
>> >>> >> >  *
>> >>> >> >  * @param doc The document to get the page from.
>> >>> >> >  *
>> >>> >> >  * @return The page that this outline will go to when activated
>> or
>> >>> null
>> >>> >> if
>> >>> >> > it does not point to anything.
>> >>> >> >  * @throws IOException If there is an error when trying to find
>> the
>> >>> >> page.
>> >>> >> >  */
>> >>> >> > public PDPage findDestinationPage( PDDocument doc ) throws
>> >>> IOException
>> >>> >> >
>> >>> >> > I didn't test it, but theoretically it looks like the piece of
>> code
>> >>> you
>> >>> >> are
>> >>> >> > looking for.
>> >>> >> >
>> >>> >> > BR
>> >>> >> > Andreas Lehmkühler
>> >>> >> >
>> >>> >> >
>> >>> >> >
>> >>> >> >> On Wed, May 19, 2010 at 12:45 PM, Kevin Brown <kb1381@gmail.com
>> >
>> >>> wrote:
>> >>> >> >>
>> >>> >> >>  Thanks. I do need to do that!
>> >>> >> >>>
>> >>> >> >>> At the moment I'm trying to see if I can get the
>> >>> >> >>> GotoSecondBookmarkOnOpen.java sample has any clues... if
>> >>> PDOutlineItem
>> >>> >> >>> could refer to a named destination then I may be in business!
>> >>> >> >>>
>> >>> >> >>>
>> >>> >> >>>
>> >>> >> >>> On Wed, May 19, 2010 at 11:57 AM, <Ad...@swmc.com> wrote:
>> >>> >> >>>
>> >>> >> >>>  I haven't dealt with named destinations, but if you get get
>> the
>> >>> >> object
>> >>> >> >>>> ID
>> >>> >> >>>> of the page, you can look up the page number with
>> >>> doc.getPageMap().
>> >>> >> If
>> >>> >> >>>> you haven't already, I'd suggest tracing through a PDF with a
>> hex
>> >>> >> editor
>> >>> >> >>>> (or any good quality text editor will work fine) to find out
>> how
>> >>> >> >>>> everything is connected.
>> >>> >> >>>>
>> >>> >> >>>> ----
>> >>> >> >>>> Thanks,
>> >>> >> >>>> Adam
>> >>> >> >>>>
>> >>> >> >>>>
>> >>> >> >>>>
>> >>> >> >>>>
>> >>> >> >>>>
>> >>> >> >>>> From:
>> >>> >> >>>> Kevin Brown <kb...@gmail.com>
>> >>> >> >>>> To:
>> >>> >> >>>> users@pdfbox.apache.org
>> >>> >> >>>> Date:
>> >>> >> >>>> 05/19/2010 08:42
>> >>> >> >>>> Subject:
>> >>> >> >>>> getting page numbers of named destinations
>> >>> >> >>>>
>> >>> >> >>>>
>> >>> >> >>>>
>> >>> >> >>>> Is it possible to, for a PDF, get the named destinations in
>> it,
>> >>> and
>> >>> >> find
>> >>> >> >>>> out
>> >>> >> >>>> what page each is on? It doesn't look like it from my perusal
>> of
>> >>> the
>> >>> >> >>>> documentation, but I'm not sure. Seems like you can get the
>> >>> >> destination
>> >>> >> >>>> names but that's about it.
>> >>> >> >>>>
>> >>> >> >>>>
>> >>> >> >>>>
>> >>> >> >>>> ?  Click here to submit conditions
>> >>> >> >>>>
>> >>> >> >>>> This email and any content within or attached hereto from  Sun
>> >>> West
>> >>> >> >>>> Mortgage Company, Inc.  is confidential and/or legally
>> privileged.
>> >>> >> The
>> >>> >> >>>> information is intended only for the use of the individual or
>> >>> entity
>> >>> >> >>>> named
>> >>> >> >>>> on this email. If you are not the intended recipient, you are
>> >>> hereby
>> >>> >> >>>> notified that any disclosure, copying, distribution or the
>> taking
>> >>> of
>> >>> >> any
>> >>> >> >>>> action in reliance on the contents of this email information
>> is
>> >>> >> strictly
>> >>> >> >>>> prohibited, and that the documents should be returned to this
>> >>> office
>> >>> >> >>>> immediately by email. Receipt by anyone other than the
>> intended
>> >>> >> >>>> recipient is
>> >>> >> >>>> not a waiver of any privilege. Please do not include your
>> social
>> >>> >> >>>> security
>> >>> >> >>>> number, account number, or any other personal or financial
>> >>> >> information
>> >>> >> >>>> in
>> >>> >> >>>> the content of the email. Should you have any questions,
>> please
>> >>> call
>> >>> >> >>>>  (800)
>> >>> >> >>>> 453 7884.
>> >>> >> >>>>
>> >>> >> >>>
>> >>> >> >>>
>> >>> >> >>>
>> >>> >> >>
>> >>> >> >
>> >>> >>
>> >>> >>
>> >>> >>
>> >>> >> ?  Click here to submit conditions
>> >>> >>
>> >>> >> This email and any content within or attached hereto from  Sun West
>> >>> >> Mortgage Company, Inc.  is confidential and/or legally privileged.
>> The
>> >>> >> information is intended only for the use of the individual or
>> entity
>> >>> named
>> >>> >> on this email. If you are not the intended recipient, you are
>> hereby
>> >>> >> notified that any disclosure, copying, distribution or the taking
>> of
>> >>> any
>> >>> >> action in reliance on the contents of this email information is
>> >>> strictly
>> >>> >> prohibited, and that the documents should be returned to this
>> office
>> >>> >> immediately by email. Receipt by anyone other than the intended
>> >>> recipient is
>> >>> >> not a waiver of any privilege. Please do not include your social
>> >>> security
>> >>> >> number, account number, or any other personal or financial
>> information
>> >>> in
>> >>> >> the content of the email. Should you have any questions, please
>> call
>> >>> (800)
>> >>> >> 453 7884.
>> >>> >>
>> >>> >
>> >>>
>> >>>
>> >>> ?  Click here to submit conditions
>> >>>
>> >>> This email and any content within or attached hereto from  Sun West
>> >>> Mortgage Company, Inc.  is confidential and/or legally privileged. The
>> >>> information is intended only for the use of the individual or entity
>> named
>> >>> on this email. If you are not the intended recipient, you are hereby
>> >>> notified that any disclosure, copying, distribution or the taking of
>> any
>> >>> action in reliance on the contents of this email information is
>> strictly
>> >>> prohibited, and that the documents should be returned to this office
>> >>> immediately by email. Receipt by anyone other than the intended
>> recipient is
>> >>> not a waiver of any privilege. Please do not include your social
>> security
>> >>> number, account number, or any other personal or financial information
>> in
>> >>> the content of the email. Should you have any questions, please call
>>  (800)
>> >>> 453 7884.
>> >>>
>> >>
>> >>
>> >
>>
>
>