Introduction
PDF annotations cover a wide range of interactive and visual elements layered on top
of page content: sticky text notes, hyperlinks, highlighted or struck-through text,
geometric shapes, ink strokes, file attachments, and approval stamps. Aspose.PDF FOSS
for C++ represents every one of these as a concrete subclass of Annotation, so code
that walks a page’s annotations can work generically against the base class while
still reaching subtype-specific members — such as Icon() on a TextAnnotation or
Action() on a LinkAnnotation — when needed.
The library’s Annotations::AnnotationType enum enumerates the subtypes it
recognizes: Text, Link, FreeText, Line, Square, Circle, Polygon,
PolyLine, Highlight, Underline, Squiggly, StrikeOut, Stamp, Caret,
Ink, Popup, FileAttachment, Sound, Movie, Widget, Screen, PrinterMark,
Watermark, Redaction, RichMedia, and several others. Each value maps to a
concrete class — CircleAnnotation, SquareAnnotation, PolygonAnnotation,
PolylineAnnotation, and LineAnnotation for shape markup; FreeTextAnnotation and
InkAnnotation for free-form text and drawn strokes; FileAttachmentAnnotation,
SoundAnnotation, MovieAnnotation, ScreenAnnotation, and RichMediaAnnotation
for embedded content; and WidgetAnnotation for AcroForm field appearances.
This post covers the Annotation and AnnotationCollection base API, adding text
notes and links, detecting annotation types when loading an existing document, and
reading or updating markup metadata and stamps. Aspose.PDF FOSS for C++ is a C++20
library with no runtime dependencies beyond the standard library; headers are
included directly from the aspose/pdf/annotations/ directory and the library
builds as a CMake target.
What’s Included
Annotation and AnnotationCollection
Annotation is the base class for every annotation subtype. It exposes shared
properties: Rect() / Rect(value) for the annotation’s bounding rectangle,
Contents() for the associated text, Name(), Color(), Flags() (an
AnnotationFlags bitmask — Print, Hidden, Invisible, NoZoom, ReadOnly, and
others), Border(), Width() / Height(), AnnotationType(), and PageIndex().
AnnotationCollection holds the annotations on a single page and is reached through
Page.Annotations().
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/annotations/annotation_collection.hpp>
#include <iostream>
using namespace Aspose::Pdf;
using namespace Aspose::Pdf::Annotations;
Document doc("reviewed.pdf");
AnnotationCollection& annots = doc.Pages()[1].Annotations();
std::cout << "Annotation count: " << annots.Count() << "\n";
for (int i = 0; i < annots.Count(); ++i) {
Annotation& a = annots[i];
std::cout << " " << a.Name() << ": " << a.Contents() << "\n";
}
AnnotationCollection also exposes Add(annotation), Add(annotation, considerRotation), Delete(index), Delete(annotation), Clear(),
Remove(annotation), Contains(annotation), and IsReadOnly().
Text Notes with TextAnnotation
TextAnnotation represents the familiar sticky-note comment. Beyond the base
Annotation members, it adds Open() / Open(value) to control whether the note
appears expanded, and Icon() / Icon(value) (a TextIcon value such as Note,
Comment, Key, Help, or Check) to choose the icon glyph.
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/annotations/text_annotation.hpp>
using namespace Aspose::Pdf;
using namespace Aspose::Pdf::Annotations;
Document doc("input.pdf");
TextAnnotation note{doc};
note.Rect(Rectangle{100.0, 700.0, 200.0, 720.0, false});
note.Contents("Reviewed by QA");
note.Icon(TextIcon::Comment);
note.Open(true);
doc.Pages()[1].Annotations().Add(note);
doc.Save("annotated.pdf");
Links and Actions with LinkAnnotation
LinkAnnotation attaches a clickable region to a page. It is constructed from the
owning Page and a Rectangle, and its behavior is set with Action(value) — any
PdfAction subclass, including NamedAction (predefined navigation such as
PredefinedAction::LastPage), GoToAction, GoToURIAction, or JavascriptAction.
Destination() reads the link’s IAppointment target, and Highlighting() /
Highlighting(value) sets the HighlightingMode (None, Invert, Outline,
Push, Toggle) applied when the link is activated.
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/annotations/link_annotation.hpp>
#include <aspose/pdf/annotations/named_action.hpp>
using namespace Aspose::Pdf;
using namespace Aspose::Pdf::Annotations;
Document doc;
Page page = doc.Pages().Add();
LinkAnnotation link{page, Rectangle{0.0, 0.0, 100.0, 20.0, false}};
link.Action(NamedAction{PredefinedAction::LastPage});
link.Highlighting(HighlightingMode::Push);
page.Annotations().Add(link);
Detecting Annotation Types on Load
When a document is opened, existing annotations are already populated in each page’s
AnnotationCollection, and AnnotationType() identifies which concrete subtype each
entry represents. This lets calling code branch on the enum value without knowing in
advance which annotation types a given PDF contains.
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/annotations/annotation_type.hpp>
#include <iostream>
using namespace Aspose::Pdf;
using namespace Aspose::Pdf::Annotations;
Document doc("mixed-annotations.pdf");
auto& annots = doc.Pages()[1].Annotations();
for (int i = 0; i < annots.Count(); ++i) {
switch (annots[i].AnnotationType()) {
case AnnotationType::Text: std::cout << "Text note\n"; break;
case AnnotationType::Link: std::cout << "Link\n"; break;
case AnnotationType::Circle: std::cout << "Circle shape\n"; break;
case AnnotationType::Square: std::cout << "Square shape\n"; break;
case AnnotationType::Highlight: std::cout << "Highlight\n"; break;
case AnnotationType::Stamp: std::cout << "Stamp\n"; break;
default: break;
}
}
Markup Annotation Metadata
MarkupAnnotation is the base for annotations that carry reviewer metadata:
Title() (the author), Subject(), RichText() for formatted comment text, and
Opacity() for blending against page content. InReplyTo() and Popup() connect a
markup annotation to the comment thread it belongs to, and ClearState() /
SetReviewState(state, userName) manage its review status. HighlightAnnotation,
UnderlineAnnotation, StrikeOutAnnotation, and SquigglyAnnotation are markup
subtypes positioned over text; their shared TextMarkupAnnotation base adds
QuadPoints() to define the quadrilateral regions covered and GetMarkedText() to
read back the text underneath.
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/annotations/markup_annotation.hpp>
using namespace Aspose::Pdf::Annotations;
for (int i = 0; i < annots.Count(); ++i) {
if (auto* markup = dynamic_cast<MarkupAnnotation*>(&annots[i])) {
markup->Title("QA Reviewer");
markup->Subject("Layout issue");
markup->Opacity(0.6);
}
}
Stamp Annotations with StampAnnotation
StampAnnotation places a predefined or custom stamp on a page. Icon() /
Icon(value) selects a StampIcon value — Approved, Draft, Confidential,
Final, Expired, NotApproved, ForComment, TopSecret, and others — and
Image() / Image(value) supplies raw image bytes for a custom stamp appearance
instead of a built-in icon.
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/annotations/stamp_annotation.hpp>
using namespace Aspose::Pdf::Annotations;
for (int i = 0; i < annots.Count(); ++i) {
if (auto* stamp = dynamic_cast<StampAnnotation*>(&annots[i])) {
stamp->Icon(StampIcon::Approved);
}
}
Quick Start
Add the library as a CMake subdirectory and link against the aspose_pdf_foss
target:
add_subdirectory(aspose.pdf-foss-for-cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)
Open a document, add a text note, and read the annotation count back:
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/annotations/text_annotation.hpp>
#include <iostream>
using namespace Aspose::Pdf;
using namespace Aspose::Pdf::Annotations;
int main() {
Document doc("input.pdf");
TextAnnotation note{doc};
note.Rect(Rectangle{100.0, 700.0, 200.0, 720.0, false});
note.Contents("Reviewed by QA");
note.Icon(TextIcon::Comment);
doc.Pages()[1].Annotations().Add(note);
doc.Save("annotated.pdf");
std::cout << "Annotations on page 1: "
<< doc.Pages()[1].Annotations().Count() << "\n";
}
Supported Formats
| Format | Extension | Read | Write |
|---|---|---|---|
| BMP | .bmp | — | ✓ |
| JPEG | .jpg | — | ✓ |
| TIFF | .tiff | — | ✓ |
| Text | .txt | — | ✓ |
| SVG | .svg | ✓ | — |
Format support applies to page rendering and load options at the document level;
these entries reflect confirmed export (BmpDevice, JpegDevice, TiffDevice,
TextDevice) and import (SvgLoadOptions) paths rather than annotation-specific
serialization.
Open Source & Licensing
Aspose.PDF FOSS for C++ is released under the MIT license. Source code is available
at https://github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Cpp, and the library can
be used in commercial and open-source projects without licensing fees.