Paul Vinkenoog wrote:
I've recently re-implemented the full internal links behaviour in the
PDF renderer. (I produce documentation for the Firebird project. FOP
0.93 solved a lot of our problems but we make use of links
extensively, and having them land on the top of the page was a
At this point, everything works fine for our purposes, but of course I
would like it to be of use for others as well, and acceptable to the
Actually I didn't want to discuss my changes until Jay Bryant
committed his named destination implementation, because I suspect he's
altered some code that I've also touched. But that hasn't happened
yet, and I'll soon be in a situation where I may be too busy to work
on this, so...
Its best to submit your patch anyway with a subject of [PATCH] at
http://issues.apache.org/bugzilla/enter_bug.cgi. Even if the patch is
not commited, at least other FOP developers will at least be able to try
out your work and provide you with some early feedback :-).
First, I would like your opinion(s) on the way link information is
passed from the layout phase to the renderer.
Currently, this is done as follows:
- Link areas have an INTERNAL_LINK trait containing the unique
PageViewport key of the target ('P1', 'P2' etc.).
- Bookmarks have a getPageViewport() method which returns a direct
reference to the target PageViewport.
IMO, the on-page target position should ideally be resolved during the
layout phase, so that all renderers can benefit from it. I suppose
that the information necessary could be made available at the moment
addAreas is called on the LayoutManager - except that there may be
some inline shift if page number citatons are resolved later?
But I'm afraid the layout code (especially the Knuth dance) is so
complicated that I couldn't master it in the time I had available.
I'm sorry about that, but please bear in mind that this was my first
introduction to the FOP source code ever.
Then an answer (to another person's question) on the fop-user list put
me in the right direction: keep track of the positions in the
renderer. So that's what I did.
For now, I've kept the existing functionality (see above) intact, both
as a fallback and because some other renderers may need it (although
within FOP itself, only PDFRenderer picks up INTERNAL_LINK traits).
To pass a link area's target ID to the renderer (bookmarks already
have it on board), I've revived the ID_LINK trait (it was commented
out in Trait.java). My internal link areas now carry the following
ID_LINK : The target ID
INTERNAL_LINK : The PV key string
This is not exactly elegant, of course. Some alternatives are:
- Create an internal link class carrying those two strings (or maybe
rather a PageViewport field and an ID string), and make the
INTERNAL_LINK trait of that class.
- Since we're resolving target areas in the renderer anyway, drop the
PV key/reference altogether and pass the ID exclusively, be it in
ID_LINK or in INTERNAL_LINK.
Both are easy to implement, but again, they may break custom renderers
that expect INTERNAL_LINK to be a string containing the PVkey. (The
first alternative allows custom renderers to adapt; with the second,
the page reference is completely lost.)
I'd like to know which solution you - the FOP developers - prefer.
That is, if my approach of resolving the links in the renderer is
acceptable at all.
Without spending a lot of time doing my own investigation work and just
reading from your description of the solutions I prefer the idea of
creating an internal link class to encapsulate the two strings - this
should provide us with more flexibility and a standard interface that
can be used across renderers.