Open cleitner opened 10 years ago
What version of the PDF spec was this introduced in? How is the support in various PDF readers? Is an annotation using /AP
expected to also have /Rect
as a fallback?
IIRC its available since PDF 1.2. /Rect
is still required and acts as a fallback/bounding box.
As for the reader support I don't know. Readers have to support appearance streams for any non-rect annotations.
Readers have to support appearance streams for any non-rect annotations.
That's of course not true. PDF defines a set of presentational annotations as well, but limited to basic shapes.
For reference, the appearance streams are described in chapter 12.5.5 (PDF32000_2008).
It's should be possible with cairo's implementation of links.
It's should be possible with cairo's implementation of links.
It also should be possible with pydyf.
I couldn't get appearance streams to work, but QuadPoints
seem to be the way to go for the normal usecase of multiple rects for a single link:
document = pydyf.PDF()
annot = pydyf.Dictionary({
"Type": "/Annot",
"Subtype": "/Link",
"Rect": pydyf.Array([ 1, 2, 9, 7 ]),
"QuadPoints": pydyf.Array([
# bl br tl tr (spec is wrong according to
# https://github.com/highkite/pdfAnnotate?tab=readme-ov-file#quadpoints)
1, 2, 6, 2, 1, 5, 6, 5,
4, 4, 7, 4, 4, 7, 7, 7,
]),
"Border": pydyf.Array([ 0, 0, 1 ]), # usually [0, 0, 0], but highlights the regions for this example
"C": pydyf.Array([ 1, 0, 1 ]),
"A": pydyf.Dictionary({
"S": "/URI",
"URI": pydyf.String("https://weasyprint.org/"),
}),
})
document.add_object(annot)
document.add_page(pydyf.Dictionary({
"Type": "/Page",
"Parent": document.pages.reference,
"Contents": pydyf.Array([]),
"Annots": pydyf.Array([ annot.reference, ]),
"MediaBox": pydyf.Array([0, 0, 10, 10]),
}))
Output: multi_rect_link.pdf
Tested with pdf.js and Preview.app.
I couldn't get appearance streams to work, but
QuadPoints
seem to be the way to go for the normal usecase of multiple rects for a single link:
That’s interesting, thanks for sharing!
The current implementation of PDF hyperlinks uses the annotation rectangle
/Rect
and splits a link into multiple annotations to support links spaning multiple lines.It might be possible to use an appearance stream
/AP
to render such links as a complex shape of multiple rectangles in a single annotation. This would allow a reader to highlight the complete link if hovered or clicked and not only the active segment. An additional benefit would be the ability to support<area>
hyperlinks with complex shapes.There might be usability problems though, if readers chose to ignore
/AP
and use the simpler/Rect
rectangle instead, which acts as a bounding box.