How can I add decorations to an annotation?

Question:

I want to add some extra content, such as text, to annotations, such as the line annotation. How do I do that?

Answer:

The best thing to do is use our default appearance, and then overlay with your own content.

After calling Annot.RefreshAppearance, you would call something like the following.

static public void AddDecorations(Annots.Line line, PDFDoc doc)
{
ElementReader reader = new ElementReader();
ElementWriter writer = new ElementWriter();
ElementBuilder builder = new ElementBuilder();

writer.Begin(doc); // start new content stream

SDF.Obj old_app_stm = line.GetAppearance();
reader.Begin(old_app_stm);

Element element;
// isolate PDFNet default appearance in group
writer.WriteElement(builder.CreateGroupBegin());
while ((element = reader.Next()) != null)
{
writer.WriteElement(element);
}
element = builder.CreateGroupEnd();
writer.WriteElement(element);

/////////////////////////////////////////////////////
// Create matrix to position and rotate new text
Point start_pt = line.GetStartPoint();
Point end_pt = line.GetEndPoint();
double xDiff = end_pt.x - start_pt.x;
double yDiff = end_pt.y - start_pt.y;
double angle = Math.Atan2(yDiff, xDiff);
Matrix2D mtx = Matrix2D.RotationMatrix(-angle);
mtx.m_h = start_pt.x;
mtx.m_v = start_pt.y;
/////////////////////////////////////////////////////

element = builder.CreateTextBegin(Font.Create(doc, Font.StandardType1Font.e_helvetica_bold), 8);
writer.WriteElement(element);
element = builder.CreateTextRun(String.Format("{0}", line.GetSDFObj().GetObjNum()));
element.SetTextMatrix(mtx);
writer.WriteElement(element);
Rect new_bbox = new Rect();
element.GetBBox(new_bbox);
element = builder.CreateTextEnd();
writer.WriteElement(element);

// update bounding boxes
Rect old_bbox = new Rect(old_app_stm.FindObj("BBox"));
old_bbox.Normalize(); // make sure x1,y1 is bottom left
new_bbox.Normalize();
new_bbox = new Rect(Math.Min(new_bbox.x1, old_bbox.x1), Math.Min(new_bbox.y1, old_bbox.y1), Math.Max(new_bbox.x2, old_bbox.x2), Math.Max(new_bbox.y2, old_bbox.y2));
SDF.Obj new_app_stm = writer.End();
new_app_stm.PutRect("BBox", new_bbox.x1, new_bbox.y1, new_bbox.x2, new_bbox.y2);
line.SetRect(new_bbox);

line.SetAppearance(new_app_stm);
}

Essentially, you wrap the pre-existing drawing elements in a group, and then write your own new content. Then update the bounding box rectangle, and update the appearance stream and annotation bounding boxes.

Another customer asked how to change the opacity of annotation?

Some annotation types support this, so you would just call the API for that type.

But some annotation types don’t support it, such as Sticky Note annots. So the following code shows this simpler customization to the default appereance.

static public void ChangeOpacity(Annot annot, PDFDoc doc)
{
	ElementReader reader = new ElementReader();
	ElementWriter writer = new ElementWriter();
	ElementBuilder builder = new ElementBuilder();

	writer.Begin(doc); // start new content stream
	Obj old_app_stm = annot.GetAppearance();
	reader.Begin(old_app_stm);

	Element element;
	double my_opacity = 0.2;

	while ((element = reader.Next()) != null)
	{
		GState gs = element.GetGState();
		gs.SetFillOpacity(my_opacity);
		gs.SetStrokeOpacity(my_opacity);
		writer.WriteElement(element);
	}
	// not changing the size of the appearance so keep BBox value
	Obj new_app_stm = writer.End();
	new_app_stm.Put("BBox", old_app_stm.FindObj("BBox"));

	annot.SetAppearance(new_app_stm);
}

Our latest SDK versions now support Line annotations with Captions.

SetShowCaption
https://www.pdftron.com/api/PDFTronSDK/dotnet/pdftron.PDF.Annots.Line.html#pdftron_PDF_Annots_Line_SetShowCaption_System_Boolean_

SetCaptionPosition
https://www.pdftron.com/api/PDFTronSDK/dotnet/pdftron.PDF.Annots.Line.html#pdftron_PDF_Annots_Line_SetCaptionPosition_pdftron_PDF_Annots_Line_CapPos_

SetContents

https://www.pdftron.com/api/PDFTronSDK/dotnet/pdftron.PDF.Annot.html#pdftron_PDF_Annot_SetContents_System_String_

For example

Line line = Line.Create(pdfdoc, new Rect(250, 250, 400, 400));
line.SetStartPoint(new Point(260, 370));
line.SetEndPoint(new Point(350, 250));
line.SetContents("Line Annotation Caption");
line.SetCaptionPosition(Line.CapPos.e_Top);
line.SetShowCaption(true);
line.SetColor(new ColorPt(1, 0, 1), 3);
line.RefreshAppearance();
pdfdoc.GetPage(1).AnnotPushBack(line);