Annotations
An annotation is a separate object attached to a page rather than part of the page
content. It has its own dictionary, its own rectangle on the page, and it lives in the
page’s /Annots array. Adding one leaves the existing content stream untouched, which
is what makes annotations the right tool for marking up a document you did not
generate: highlights, review comments, callout shapes, attached files.
In UniPDF the annotation objects themselves are in the model package, one Go type per
PDF subtype: PdfAnnotationSquare, PdfAnnotationCircle, PdfAnnotationLine and so
on. Each has a constructor, NewPdfAnnotationSquare() and friends, and each embeds
*PdfAnnotation carrying the entries common to every annotation, including Rect and
AP. You attach one with page.AddAnnotation(annot) and read the existing ones back
with page.GetAnnotations().
Appearance streams
Most annotation types are allowed to have no appearance of their own. The viewer is
then free to draw whatever it likes, which is why the same annotated file can look
different in Acrobat, Preview and a browser’s built-in viewer. The fix is an appearance
stream: a small form XObject stored under the annotation’s AP entry that says exactly
what to draw.
That is what the annotator package adds on top of model. Its Create...Annotation
functions take a definition struct describing geometry, color and opacity, build the
appearance stream, and return a *model.PdfAnnotation with AP and Rect already
filled in. CreateCircleAnnotation, CreateRectangleAnnotation and
CreateLineAnnotation all follow that shape. Reach for model directly when you only
need the annotation data, and for annotator when the annotation has to look the same
everywhere.
Note that annotator sets Rect from the bounding box it computes, not from the
coordinates you passed in, and the three shape helpers do not agree on how. For a
rectangle it comes out as exactly the position and size you asked for. For a line it is
the bounding box of the polygon actually drawn, so it reaches slightly past the
endpoints. For a circle the offset is applied twice, putting the shape at double the
coordinates you gave; see ellipse annotation for the detail and
the workaround.
Supported annotation types
UniPDF has model types for the common annotation subtypes:
- Text markup: Highlight, Underline, StrikeOut, Squiggly
- Shapes: Circle, Square, Line, Polygon, PolyLine
- Text, the sticky note
- Ink
- Redact
- Stamp
- Link
- Sound and RichMedia
- Widget, used for form fields
- FileAttachment
The annotator package generates appearance streams for a smaller set: circles and
ellipses, rectangles, lines, ink, and the widget appearances used by form fields.
Where to look
| Guide | Covers |
|---|---|
| List annotations | Reading the annotations already on a page and identifying their subtype. |
| Text annotation | Sticky-note comments, and why they need no appearance stream. |
| Rectangle annotation | Filled and outlined rectangles with annotator. |
| Ellipse annotation | Circles and ellipses, and how the definition maps to the bounding box. |
| Line annotation | Lines between two points, including line endings. |
| File attachment | Embedding a file in the document and anchoring it to a page. |
Widget annotations are covered separately under the forms guides, since their appearance is driven by the field rather than set directly.