How do I create circle, freehand, or any other annotation type?

Q:

Just a quick general question on pdftron's annotation capabilities.

I saw in the annotation sample project it's possible to add hyperlinks
and text annotation boxes to the pdf document.

Is there any support for saving a free hand drawing as a custom
annotation type that gets scaled as the document is zoomed in/out? For
instance, letting the user draw a circle shape, then saving it as a
layer into the pdf document. I don't want to save the circle shape
directly into the pdf page, but rather as a separate layer of sorts.
----

A:
Using PDFNet SDK you can create any type of annotations (including
custom annotation types).

For example, you can create a circle annotation as follows (assuming
you are using C#):

Annot circle = Annot.CreateLink(doc, pdftron.PDF.Annot.e_Circle, new
Rect(85, 458, 503, 502));

// Set the annotation border witdth to 3 points...
circle.SetBorderStyle(new
Annot.BorderStyle(Annot.BorderStyle.Style.e_solid, 3));
circle.SetColor(new ColorPt(0, 0, 1));

// Add the annotation to the first page
page.AnnotPushBack(circle);

Similarly you can create any other annotation type. For a detailed
description of all standard PDF annotation types, please refer to
section 8.4.5 'Annotation Types' in 'PDF Reference Manual'.

Even if PDFNet does not provide a specific high-level method to set a
property in annotation dictionary, you can easily add or edit
properties using SDF/Cos API.

The following example illustrates how to create 'ink' annotation (an
ink annotation represents a freehand "scribble" composed of one or
more disjoint paths).

Annot scribble = Annot.CreateLink(doc, pdftron.PDF.Annot.e_Ink, new
Rect(109, 572, 170, 621));

// Get annotation dictionary and add path strokes
pdftron.SDF.Obj scr = scribble.GetSDFObj();

// Create an array of n arrays, each representing a stroked path.
// Each array is a series of alternating horizontal and vertical
// coordinates in default user space, specifying points along the
path.
Obj strokes = Obj.CreateArray();
Obj stk1 = Obj.CreateArray();
strokes.PushBack(stk1);
stk1.PushBack(Obj.CreateNumber(140));
stk1.PushBack(Obj.CreateNumber(610));
stk1.PushBack(Obj.CreateNumber(120));
stk1.PushBack(Obj.CreateNumber(600));
stk1.PushBack(Obj.CreateNumber(110));
stk1.PushBack(Obj.CreateNumber(580));
stk1.PushBack(Obj.CreateNumber(169));
stk1.PushBack(Obj.CreateNumber(575));
...

scr.Put("InkList", strokes);

page.AnnotPushBack(scribble);

Q:

Thanks for the help. Do you have these samples in C++?
---
A:

Except for minor syntax differences C++ code is essentially the same.
The code would look along the following lines:

Annot circle = Annot::CreateLink(doc, Annot::e_Circle, Rect(85, 458,
503, 502));

// Set the annotation border witdth to 3 points...
Annot::BorderStyle bs(Annot::BorderStyle::e_solid, 3)
circle.SetBorderStyle(bs);
circle.SetColor(ColorPt(0, 0, 1));

// Add the annotation to the first page
page.AnnotPushBack(circle);

... for scribble annotation ...

Annot scribble = Annot::CreateLink(doc, Annot::e_Ink, Rect(109, 572,
170, 621));

// Get annotation dictionary and add path strokes
Obj* scr = scribble.GetSDFObj();

// Create an array of n arrays, each representing a stroked path.
// Each array is a series of alternating horizontal and vertical
// coordinates in default user space, specifying points along the
path.
Obj* strokes = new Array();
Obj* stk1 = new Array();
strokes->PushBack(stk1);
stk1->PushBack(new Number(140)); stk1.PushBack(new Number(610));
stk1->PushBack(new Number(120)); stk1.PushBack(new Number(600));
stk1->PushBack(new Number(110)); stk1.PushBack(new Number(580));
stk1->PushBack(new Number(169)); stk1.PushBack(new Number(575));
...
scr->Put("InkList", strokes);
page.AnnotPushBack(scribble);