Search code examples
freemarkerxsl-fo

Area attribute in xsl-fo external-graphic with coordinates


I have a requirement where I need to portray an image using xsl-fo and the user should be able to click within the text / particular location of the image. To explain it further,

  • I have an image
  • It contains text
  • I have the co-ordinates of where the text occurs and need to provide hyper-link for those co-ordinates.

So, when I click on the text, I should be able to traverse to another location in the PDF document.

I have tried with <area> tag mentioning the co-ordinates within <fo:block>, but it does not work. My Fo structure is as follows:

<fo:block> <fo:external-graphic content-width="scale-to-fit" content-height="100%" width="100%" src="figures/test.png"/><area shape="rect" coords="148,147,195,162" <fo:basic-link>xyz</fo:basic-link></area>
</fo:block>

Could you please let me know if anyone has tried something like this and help me out?


Solution

  • While XSL-FO does not have image maps (something analogous to the MAP element in HTML), it is possible to use an embedded SVG document to achieve the same result.

    Have a look at this example:

    <fo:block>
        <fo:instream-foreign-object>
            <svg width="5cm" height="3cm" viewBox="0 0 5 3" version="1.1"
                 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
                <image x="0" y="0" width="5" height="3" xlink:href="image.png"/>
                <a xlink:href="http://www.w3.org">
                    <rect x="1" y="2" width="3" height="1" 
                          fill="#AAFFFF" stroke="none" opacity="0"/>
                </a>
            </svg>
        </fo:instream-foreign-object>
    </fo:block>
    

    Inside the svg document:

    • an image element places the bitmap image, having the same size of the document viewBox
    • an a element defines the link destination
    • a rect element inside the a defines the clickable area

    I tested this example with FOP 2.1 and it works, with a couple of caveat:

    • in order to make the clickable rectangle completely transparent I used opacity="0"; I tried using fill="none" stroke="none" but this was not working, probably because the rectangle was completely discarded / ignored not having any visible mark
    • the clickable area in the PDF is rectangular even when using an ellipse element in the SVG