> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/core/get-started/samples/annotationtest.md).

# PDF Annotation - Add/Edit

Sample code to use Apryse Server SDK to add or edit PDF annotations. Link, stamp, file attachment, sound, text, free-text, line, circle, square, polygon, polyline, highlight, squiggly, caret, ink.  Sa

Sample code to use Apryse Server SDK for adding or editing PDF annotations. The annotation types included in this sample are: hyperlink, intra-document link, stamp, rubber stamp, file attachment, sound, text, free-text, line, circle, square, polygon, polyline, highlight, squiggly, caret, and ink. Learn more about our [Server SDK](/core/get-started/get-started.md) and [PDF Annotation Library](/core/annotation/annotation.md).

{% tabs %}
{% tab title="C#" %}
{% code lineNumbers="true" %}

```csharp
//
// Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
//

using pdftron;
using pdftron.Common;
using pdftron.Filters;
using pdftron.SDF;
using pdftron.PDF;
using pdftron.PDF.Annots;

namespace AnnotationTestCS
{
	/// <summary>
	/// Summary description for Class1.
	/// </summary>
	class Class1
	{
		private static pdftron.PDFNetLoader pdfNetLoader = pdftron.PDFNetLoader.Instance();
		static Class1() {}

		private static void AnnotationHighLevelAPI(PDFDoc doc)
		{
			// The following code snippet traverses all annotations in the document
			System.Console.WriteLine("Traversing all annotations in the document...");

			string uri;
			int page_num = 1;
			for (PageIterator itr = doc.GetPageIterator(); itr.HasNext(); itr.Next())
			{
				System.Console.WriteLine("Page " + page_num++ + ": ");

				Page page = itr.Current();
				int num_annots = page.GetNumAnnots();
				for (int i = 0; i < num_annots; ++i)
				{
					Annot annot = page.GetAnnot(i);
					if (annot == null || !annot.IsValid()) continue;
					System.Console.WriteLine("Annot Type: " + annot.GetSDFObj().Get("Subtype").Value().GetName());

					Rect bbox = annot.GetRect();
					System.Console.WriteLine("  Position: " + bbox.x1
						+ ", " + bbox.y1
						+ ", " + bbox.x2
						+ ", " + bbox.y2);

					switch (annot.GetType())
					{
						case Annot.Type.e_Link:
							{
								Link lnk = new Link(annot);
								Action action = lnk.GetAction();
								if (action == null || !action.IsValid()) continue;
								if (action.GetType() == Action.Type.e_GoTo)
								{
									Destination dest = action.GetDest();
									if (!dest.IsValid())
									{
										System.Console.WriteLine("  Destination is not valid");
									}
									else
									{
										int pg_num = dest.GetPage().GetIndex();
										System.Console.WriteLine("  Links to: page number " + pg_num + " in this document");
									}
								}
								else if (action.GetType() == Action.Type.e_URI)
								{
									uri = action.GetSDFObj().Get("URI").Value().GetAsPDFText();
									System.Console.WriteLine("  Links to: " + uri);
								}
								// ...
							}
							break;
						case Annot.Type.e_Widget:
							break;
						case Annot.Type.e_FileAttachment:
							break;
						// ...
						default:
							break;
					}
				}
			}

			// Use the high-level API to create new annotations.
			Page first_page = doc.GetPage(1);

			// Create a hyperlink...
			Link hyperlink = Link.Create(doc, new Rect(85, 570, 503, 524), Action.CreateURI(doc, "http://www.pdftron.com"));
			first_page.AnnotPushBack(hyperlink);

			// Create an intra-document link...
			Action goto_page_3 = Action.CreateGoto(Destination.CreateFitH(doc.GetPage(3), 0));
			Link link = Link.Create(doc, new Rect(85, 458, 503, 502), goto_page_3);
			link.SetColor(new ColorPt(0, 0, 1));

			// Add the new annotation to the first page
			first_page.AnnotPushBack(link);

			// Create a stamp annotation ...
			RubberStamp stamp = RubberStamp.Create(doc, new Rect(30, 30, 300, 200));
			stamp.SetIcon("Draft");
			first_page.AnnotPushBack(stamp);

			// Create a file attachment annotation (embed the 'peppers.jpg').
			FileAttachment file_attach = FileAttachment.Create(doc, new Rect(80, 280, 108, 320), (input_path + "peppers.jpg"));
			first_page.AnnotPushBack(file_attach);


			Ink ink = Ink.Create(doc, new Rect(110, 10, 300, 200));
			Point pt3 = new Point(110, 10);
			//pt3.x = 110; pt3.y = 10;
			ink.SetPoint(0, 0, pt3);
			pt3.x = 150; pt3.y = 50;
			ink.SetPoint(0, 1, pt3);
			pt3.x = 190; pt3.y = 60;
			ink.SetPoint(0, 2, pt3);
			pt3.x = 180; pt3.y = 90;
			ink.SetPoint(1, 0, pt3);
			pt3.x = 190; pt3.y = 95;
			ink.SetPoint(1, 1, pt3);
			pt3.x = 200; pt3.y = 100;
			ink.SetPoint(1, 2, pt3);
			pt3.x = 166; pt3.y = 86;
			ink.SetPoint(2, 0, pt3);
			pt3.x = 196; pt3.y = 96;
			ink.SetPoint(2, 1, pt3);
			pt3.x = 221; pt3.y = 121;
			ink.SetPoint(2, 2, pt3);
			pt3.x = 288; pt3.y = 188;
			ink.SetPoint(2, 3, pt3);
			ink.SetColor(new ColorPt(0, 1, 1), 3);
			first_page.AnnotPushBack(ink);
		}

		static void AnnotationLowLevelAPI(PDFDoc doc)
		{
			Page page = doc.GetPage(1);

			Obj annots = page.GetAnnots();
			if (annots == null)
			{
				// If there are no annotations, create a new annotation 
				// array for the page.
				annots = doc.CreateIndirectArray();
				page.GetSDFObj().Put("Annots", annots);
			}

			// Create the Text annotation
			Obj text_annot = doc.CreateIndirectDict();
			text_annot.PutName("Subtype", "Text");
			text_annot.PutBool("Open", true);
			text_annot.PutString("Contents", "The quick brown fox ate the lazy mouse.");
			text_annot.PutRect("Rect", 266, 116, 430, 204);

			// Insert the annotation in the page annotation array
			annots.PushBack(text_annot);

			// Create a Link annotation
			Obj link1 = doc.CreateIndirectDict();
			link1.PutName("Subtype", "Link");
			Destination dest = Destination.CreateFit(doc.GetPage(2));
			link1.Put("Dest", dest.GetSDFObj());
			link1.PutRect("Rect", 85, 705, 503, 661);
			annots.PushBack(link1);

			// Create another Link annotation
			Obj link2 = doc.CreateIndirectDict();
			link2.PutName("Subtype", "Link");
			Destination dest2 = Destination.CreateFit(doc.GetPage(3));
			link2.Put("Dest", dest2.GetSDFObj());
			link2.PutRect("Rect", 85, 638, 503, 594);
			annots.PushBack(link2);

			// Note that PDFNet APi can be used to modify existing annotations. 
			// In the following example we will modify the second link annotation 
			// (link2) so that it points to the 10th page. We also use a different 
			// destination page fit type.

			link2.Put("Dest",
				Destination.CreateXYZ(doc.GetPage(10), 100, 792 - 70, 10).GetSDFObj());

			// Create a third link annotation with a hyperlink action (all other 
			// annotation types can be created in a similar way)
			Obj link3 = doc.CreateIndirectDict();
			link3.PutName("Subtype", "Link");
			link3.PutRect("Rect", 85, 570, 503, 524);

			// Create a URI action
			Obj action = link3.PutDict("A");
			action.PutName("S", "URI");
			action.PutString("URI", "http://www.pdftron.com");
			annots.PushBack(link3);
		}
		
		private static void CreateTestAnnots(PDFDoc doc) {

			ElementWriter ew = new ElementWriter();
			ElementBuilder eb = new ElementBuilder();
			Element element;

			Page first_page= doc.PageCreate(new Rect(0, 0, 600, 600));
			doc.PagePushBack(first_page);
			ew.Begin(first_page, ElementWriter.WriteMode.e_overlay, false );	// begin writing to this page
			ew.End();  // save changes to the current page

			//
			// Test of a free text annotation.
			//
			{
				FreeText txtannot = FreeText.Create( doc, new Rect(10, 400, 160, 570)  );
				txtannot.SetContents( "\n\nSome swift brown fox snatched a gray hare out of the air by freezing it with an angry glare." +
									  "\n\nAha!\n\nAnd there was much rejoicing!" );
				txtannot.SetBorderStyle( new Annot.BorderStyle( Annot.BorderStyle.Style.e_solid, 1, 10, 20 ) );
				txtannot.SetQuaddingFormat(0);
				first_page.AnnotPushBack(txtannot);
				txtannot.RefreshAppearance();
			}
			{
				FreeText txtannot = FreeText.Create( doc, new Rect(100, 100, 350, 500)  );
				txtannot.SetContentRect( new Rect( 200, 200, 350, 500 ) );
				txtannot.SetContents( "\n\nSome swift brown fox snatched a gray hare out of the air by freezing it with an angry glare." +
									  "\n\nAha!\n\nAnd there was much rejoicing!" );
				txtannot.SetCalloutLinePoints( new Point(200,300), new Point(150,290), new Point(110,110) );
				txtannot.SetBorderStyle(new Annot.BorderStyle(Annot.BorderStyle.Style.e_solid, 1, 10, 20 ) );
				txtannot.SetEndingStyle(Line.EndingStyle.e_ClosedArrow );
				txtannot.SetColor( new ColorPt( 0, 1, 0 ) );
				txtannot.SetQuaddingFormat(1);
				first_page.AnnotPushBack(txtannot);
				txtannot.RefreshAppearance();
			}
			{
				FreeText txtannot = FreeText.Create( doc, new Rect(400, 10, 550, 400)  );
				txtannot.SetContents( "\n\nSome swift brown fox snatched a gray hare out of the air by freezing it with an angry glare." +
									  "\n\nAha!\n\nAnd there was much rejoicing!" );
				txtannot.SetBorderStyle( new Annot.BorderStyle( Annot.BorderStyle.Style.e_solid, 1, 10, 20 ) );
				txtannot.SetColor( new ColorPt( 0, 0, 1 ) );
				txtannot.SetOpacity( 0.2 );
				txtannot.SetQuaddingFormat(2);
				first_page.AnnotPushBack(txtannot);
				txtannot.RefreshAppearance();
			}

			Page page= doc.PageCreate(new Rect(0, 0, 600, 600));
			doc.PagePushBack(page);
			ew.Begin(page, ElementWriter.WriteMode.e_overlay, false );	// begin writing to this page
			eb.Reset();			// Reset the GState to default
			ew.End();  // save changes to the current page

			{
				//Create a Line annotation...
				Line line = Line.Create(doc, new Rect(250, 250, 400, 400));
				line.SetStartPoint( new Point(350, 270 ) );
				line.SetEndPoint( new Point(260,370) );
				line.SetStartStyle(Line.EndingStyle.e_Square);
				line.SetEndStyle(Line.EndingStyle.e_Circle);
				line.SetColor(new ColorPt(.3, .5, 0), 3);
				line.SetContents( "Dashed Captioned" );
				line.SetShowCaption(true);
				line.SetCaptionPosition(Line.CapPos.e_Top );
				double[] dash = new double[2];
				dash[0] = 2;
				dash[1] = 2.0;
				line.SetBorderStyle( new Annot.BorderStyle( Annot.BorderStyle.Style.e_dashed, 2, 0, 0, dash ) );
				line.RefreshAppearance();
				page.AnnotPushBack(line);
			}
			{
				Line line=Line.Create(doc, new Rect(347, 377, 600, 600));
				line.SetStartPoint( new Point(385, 410 ) );
				line.SetEndPoint(new Point(540,555) );
				line.SetStartStyle(Line.EndingStyle.e_Circle);
				line.SetEndStyle(Line.EndingStyle.e_OpenArrow);
				line.SetColor(new ColorPt(1, 0, 0), 3);
				line.SetInteriorColor(new ColorPt(0, 1, 0), 3);
				line.SetContents( "Inline Caption" );
				line.SetShowCaption(true);
				line.SetCaptionPosition( Line.CapPos.e_Inline);
				line.SetLeaderLineExtensionLength( 4 );
				line.SetLeaderLineLength( -12 );
				line.SetLeaderLineOffset( 2 );
				line.RefreshAppearance();
				page.AnnotPushBack(line);
			}
			{
				Line line=Line.Create(doc, new Rect(10, 400, 200, 600));
				line.SetStartPoint(new Point(25, 426 ) );
				line.SetEndPoint(new Point(180,555) );
				line.SetStartStyle(Line.EndingStyle.e_Circle);
				line.SetEndStyle(Line.EndingStyle.e_Square);
				line.SetColor(new ColorPt(0, 0, 1), 3);
				line.SetInteriorColor(new ColorPt(1, 0, 0), 3);
				line.SetContents("Offset Caption");
				line.SetShowCaption(true);
				line.SetCaptionPosition( Line.CapPos.e_Top );
				line.SetTextHOffset( -60 );
				line.SetTextVOffset( 10 );
				line.RefreshAppearance();
				page.AnnotPushBack(line);
			}
			{
				Line line=Line.Create(doc, new Rect(200, 10, 400, 70));
				line.SetStartPoint(new Point(220, 25 ) );
				line.SetEndPoint(new Point(370,60) );
				line.SetStartStyle(Line.EndingStyle.e_Butt);
				line.SetEndStyle(Line.EndingStyle.e_OpenArrow);
				line.SetColor(new ColorPt(0, 0, 1), 3);
				line.SetContents("Regular Caption");
				line.SetShowCaption(true);
				line.SetCaptionPosition( Line.CapPos.e_Top );
				line.RefreshAppearance();
				page.AnnotPushBack(line);
			}
			{
				Line line=Line.Create(doc, new Rect(200, 70, 400, 130));
				line.SetStartPoint(new Point(220, 111 ) );
				line.SetEndPoint(new Point(370,78) );
				line.SetStartStyle(Line.EndingStyle.e_Circle);
				line.SetEndStyle(Line.EndingStyle.e_Diamond);
				line.SetContents("Circle to Diamond");
				line.SetColor(new ColorPt(0, 0, 1), 3);
				line.SetInteriorColor(new ColorPt(0, 1, 0), 3);
				line.SetShowCaption(true);
				line.SetCaptionPosition( Line.CapPos.e_Top );
				line.RefreshAppearance();
				page.AnnotPushBack(line);
			}
			{
				Line line=Line.Create(doc, new Rect(10, 100, 160, 200));
				line.SetStartPoint(new Point(15, 110 ) );
				line.SetEndPoint(new Point(150, 190) );
				line.SetStartStyle(Line.EndingStyle.e_Slash);
				line.SetEndStyle(Line.EndingStyle.e_ClosedArrow);
				line.SetContents("Slash to CArrow");
				line.SetColor(new ColorPt(1, 0, 0), 3);
				line.SetInteriorColor(new ColorPt(0, 1, 1), 3);
				line.SetShowCaption(true);
				line.SetCaptionPosition( Line.CapPos.e_Top );
				line.RefreshAppearance();
				page.AnnotPushBack(line);
			}
			{
				Line line=Line.Create(doc, new Rect( 270, 270, 570, 433 ));
				line.SetStartPoint(new Point(300, 400 ) );
				line.SetEndPoint(new Point(550, 300) );
				line.SetStartStyle(Line.EndingStyle.e_RClosedArrow);
				line.SetEndStyle(Line.EndingStyle.e_ROpenArrow);
				line.SetContents("ROpen & RClosed arrows");
				line.SetColor(new ColorPt(0, 0, 1), 3);
				line.SetInteriorColor(new ColorPt(0, 1, 0), 3);
				line.SetShowCaption(true);
				line.SetCaptionPosition( Line.CapPos.e_Top );
				line.RefreshAppearance();
				page.AnnotPushBack(line);
			}
			{
				Line line=Line.Create(doc, new Rect( 195, 395, 205, 505 ));
				line.SetStartPoint(new Point(200, 400 ) );
				line.SetEndPoint(new Point(200, 500) );
				line.RefreshAppearance();
				page.AnnotPushBack(line);
			}
			{
				Line line=Line.Create(doc, new Rect( 55, 299, 150, 301 ));
				line.SetStartPoint(new Point(55, 300 ) );
				line.SetEndPoint(new Point(155, 300) );
				line.SetStartStyle(Line.EndingStyle.e_Circle);
				line.SetEndStyle(Line.EndingStyle.e_Circle);
				line.SetContents("Caption that's longer than its line.");
				line.SetColor(new ColorPt(1, 0, 1), 3);
				line.SetInteriorColor(new ColorPt(0, 1, 0), 3);
				line.SetShowCaption(true);
				line.SetCaptionPosition( Line.CapPos.e_Top );
				line.RefreshAppearance();
				page.AnnotPushBack(line);
			}
			{
				Line line=Line.Create(doc, new Rect( 300, 200, 390, 234 ));
				line.SetStartPoint(new Point(310, 210 ) );
				line.SetEndPoint(new Point(380, 220) );
				line.SetColor(new ColorPt(0, 0, 0), 3);
				line.RefreshAppearance();
				page.AnnotPushBack(line);
			}

			Page page3 = doc.PageCreate(new Rect(0, 0, 600, 600));
			ew.Begin(page3);	// begin writing to the page
			ew.End();  // save changes to the current page
			doc.PagePushBack(page3);
			{
				Circle circle = Circle.Create(doc, new Rect( 300, 300, 390, 350 ));
				circle.SetColor(new ColorPt(0, 0, 0), 3);
				circle.RefreshAppearance();
				page3.AnnotPushBack(circle);
			}
			{
				Circle circle= Circle.Create(doc, new Rect( 100, 100, 200, 200 ));
				circle.SetColor(new ColorPt(0, 1, 0), 3);
				circle.SetInteriorColor(new ColorPt(0, 0, 1), 3);
				double[] dash = new double[2];
				dash[0]=2;dash[1]=4;
				circle.SetBorderStyle(new Annot.BorderStyle( Annot.BorderStyle.Style.e_dashed, 3, 0, 0, dash ) );
				circle.SetPadding( new Rect(2,2,2,2) );
				circle.RefreshAppearance();
				page3.AnnotPushBack(circle);
			}
			{
				Square sq = Square.Create( doc, new Rect(10,200, 80, 300 ) );
				sq.SetColor(new ColorPt(0, 0, 0), 3);
				sq.RefreshAppearance();
				page3.AnnotPushBack( sq );
			}
			{
				Square sq = Square.Create( doc, new Rect(500,200, 580, 300 ) );
				sq.SetColor(new ColorPt(1, 0, 0), 3);
				sq.SetInteriorColor(new ColorPt(0, 1, 1), 3);
				double[] dash = new double[2];
				dash[0]=4;dash[1]=2;
				sq.SetBorderStyle(new Annot.BorderStyle( Annot.BorderStyle.Style.e_dashed, 6, 0, 0, dash ) );
				sq.SetPadding( new Rect(4,4,4,4) );
				sq.RefreshAppearance();
				page3.AnnotPushBack( sq );
			}
			{
				Polygon poly = Polygon.Create(doc, new Rect(5, 500, 125, 590));
				poly.SetColor(new ColorPt(1, 0, 0), 3);
				poly.SetInteriorColor(new ColorPt(1, 1, 0), 3);
				poly.SetVertex(0, new Point(12,510) );
				poly.SetVertex(1, new Point(100,510) );
				poly.SetVertex(2, new Point(100,555) );
				poly.SetVertex(3, new Point(35,544) );
				poly.SetBorderStyle(new Annot.BorderStyle( Annot.BorderStyle.Style.e_solid, 4, 0, 0 ) );
				poly.SetPadding( new Rect(4,4,4,4) );
				poly.RefreshAppearance();
				page3.AnnotPushBack( poly );
			}
			{
				PolyLine poly = PolyLine.Create(doc, new Rect(400, 10, 500, 90));
				poly.SetColor(new ColorPt(1, 0, 0), 3);
				poly.SetInteriorColor(new ColorPt(0, 1, 0), 3);
				poly.SetVertex(0, new Point(405,20) );
				poly.SetVertex(1, new Point(440,40) );
				poly.SetVertex(2, new Point(410,60) );
				poly.SetVertex(3, new Point(470,80) );
				poly.SetBorderStyle( new Annot.BorderStyle( Annot.BorderStyle.Style.e_solid, 2, 0, 0 ) );
				poly.SetPadding( new Rect(4,4,4,4) );
				poly.SetStartStyle( Line.EndingStyle.e_RClosedArrow );
				poly.SetEndStyle( Line.EndingStyle.e_ClosedArrow );
				poly.RefreshAppearance();
				page3.AnnotPushBack( poly );
			}
			{
				Link lk = Link.Create( doc, new Rect(5,5,55,24) );
				//lk.SetColor( ColorPt(0,1,0), 3 );
				lk.RefreshAppearance();
				page3.AnnotPushBack( lk );
			}


			Page page4 = doc.PageCreate(new Rect(0, 0, 600, 600));
			ew.Begin(page4);	// begin writing to the page
			ew.End();  // save changes to the current page
			doc.PagePushBack(page4);

			{	
				ew.Begin( page4 );
				Font font = Font.Create(doc, Font.StandardType1Font.e_helvetica);
				element = eb.CreateTextBegin( font, 16 );
				element.SetPathFill(true);
				ew.WriteElement(element);
				element = eb.CreateTextRun( "Some random text on the page", font, 16 );
				element.SetTextMatrix(1, 0, 0, 1, 100, 500 );
				ew.WriteElement(element);
				ew.WriteElement( eb.CreateTextEnd() );
				ew.End();
			}
			{
				Highlight hl = Highlight.Create( doc, new Rect(100,490,150,515) );
				hl.SetColor(new ColorPt(0,1,0), 3 );
				hl.RefreshAppearance();
				page4.AnnotPushBack( hl );
			}
			{
				Squiggly sq = Squiggly.Create( doc, new Rect(100,450,250,600) );
				//sq.SetColor( ColorPt(1,0,0), 3 );
				sq.SetQuadPoint( 0, new QuadPoint(new Point( 122,455), new Point(240, 545), new Point(230, 595), new Point(101,500 ) ) );
				sq.RefreshAppearance();
				page4.AnnotPushBack( sq );
			}
			{
				Caret cr = Caret.Create( doc, new Rect(100,40,129,69) );
				cr.SetColor( new ColorPt(0,0,1), 3 );
				cr.SetSymbol( "P" );
				cr.RefreshAppearance();
				page4.AnnotPushBack( cr );
			}


			Page page5 = doc.PageCreate(new Rect(0, 0, 600, 600));
			ew.Begin(page5);	// begin writing to the page
			ew.End();  // save changes to the current page
			doc.PagePushBack(page5);
			Page page6 = doc.PageCreate(new Rect(0, 0, 600, 600));
			ew.Begin(page6);	// begin writing to the page
			ew.End();  // save changes to the current page
			doc.PagePushBack(page6);

			{
				Text txt = Text.Create( doc, new Rect( 10, 20, 30, 40 ) );
				txt.SetIcon( "UserIcon" );
				txt.SetContents( "User defined icon, unrecognized by appearance generator" );
				txt.SetColor(new ColorPt(0,1,0) );
				txt.RefreshAppearance();
				page6.AnnotPushBack( txt );
			}
			{
				Ink ink = Ink.Create( doc, new Rect( 100, 400, 200, 550 ) );
				ink.SetColor(new ColorPt(0,0,1) );
				ink.SetPoint( 1, 3, new Point( 220, 505) );
				ink.SetPoint( 1, 0, new Point( 100, 490) );
				ink.SetPoint( 0, 1, new Point( 120, 410) );
				ink.SetPoint( 0, 0, new Point( 100, 400) );
				ink.SetPoint( 1, 2, new Point( 180, 490) );
				ink.SetPoint( 1, 1, new Point( 140, 440) );		
				ink.SetBorderStyle( new Annot.BorderStyle( Annot.BorderStyle.Style.e_solid, 3, 0, 0  ) );
				ink.RefreshAppearance();
				page6.AnnotPushBack( ink );
			}


			Page page7 = doc.PageCreate(new Rect(0, 0, 600, 600));
			ew.Begin(page7);	// begin writing to the page
			ew.End();  // save changes to the current page
			doc.PagePushBack(page7);

			{
				Sound snd = Sound.Create( doc, new Rect( 100, 500, 120, 520 ) );
				snd.SetColor(  new ColorPt(1,1,0) );
				snd.SetIcon(Sound.Icon.e_Speaker );
				snd.RefreshAppearance();
				page7.AnnotPushBack( snd );
			}
			{
				Sound snd = Sound.Create( doc, new Rect( 200, 500, 220, 520 ) );
				snd.SetColor(new ColorPt(1,1,0) );
				snd.SetIcon(Sound.Icon.e_Mic );
				snd.RefreshAppearance();
				page7.AnnotPushBack( snd );
			}

			Page page8 = doc.PageCreate(new Rect(0, 0, 600, 600));
			ew.Begin(page8);	// begin writing to the page
			ew.End();  // save changes to the current page
			doc.PagePushBack(page8);

			for( int ipage =0; ipage < 2; ++ipage ) {
				double px = 5, py = 520;
				for (RubberStamp.Icon istamp = RubberStamp.Icon.e_Approved; 
					istamp <= RubberStamp.Icon.e_Draft; 
					istamp = (RubberStamp.Icon) (  (int)(istamp) + 1  ) ) {
						RubberStamp stmp = RubberStamp.Create( doc, new Rect(1,1,100,100) );
						stmp.SetIcon( istamp );
						stmp.SetContents(stmp.GetIconName());
						stmp.SetRect(new Rect(px, py, px+100, py+25 ) );
						py -= 100;
						if( py < 0 ) {
							py = 520;
							px += 200;
						}
						if( ipage == 0 ){
							//page7.AnnotPushBack( st );
							;
						}
						else {
							page8.AnnotPushBack(stmp);
							stmp.RefreshAppearance();
						}
				}
			}
			RubberStamp st = RubberStamp.Create( doc, new Rect(400,5,550,45) );
			st.SetIcon( "UserStamp" );
			st.SetContents( "User defined stamp" );
			page8.AnnotPushBack( st );
			st.RefreshAppearance();



		}


		// Relative path to the folder containing test files.
		const string input_path =  "../../../../TestFiles/";
		const string output_path = "../../../../TestFiles/Output/";

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[System.STAThread]
		static void Main(string[] args)
		{
			PDFNet.Initialize(PDFTronLicense.Key);

			try
			{
				using (PDFDoc doc = new PDFDoc(input_path + "numbered.pdf"))
				{
					doc.InitSecurityHandler();

					// An example of using SDF/Cos API to add any type of annotations.
					AnnotationLowLevelAPI(doc);
					doc.Save(output_path + "annotation_test1.pdf", SDFDoc.SaveOptions.e_linearized);
					System.Console.WriteLine("Done. Results saved in annotation_test1.pdf");
					
					// An example of using the high-level PDFNet API to read existing annotations,
					// to edit existing annotations, and to create new annotation from scratch.
					AnnotationHighLevelAPI(doc);
					doc.Save(output_path + "annotation_test2.pdf", SDFDoc.SaveOptions.e_linearized);
					System.Console.WriteLine("Done. Results saved in annotation_test2.pdf");
				}

				// an example of creating various annotations in a brand new document
				using (PDFDoc doc1 = new PDFDoc())
				{
					CreateTestAnnots(doc1);
					doc1.Save(output_path + "new_annot_test_api.pdf", SDFDoc.SaveOptions.e_linearized);
					System.Console.WriteLine("Saved new_annot_test_api.pdf");
				}
			}
			catch (PDFNetException e)
			{
				System.Console.WriteLine(e.Message);
			}
			PDFNet.Terminate();
		}
	}
}
```

{% endcode %}
{% endtab %}

{% tab title="C++" %}
{% code lineNumbers="true" %}

```cpp
//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
// Consult legal.txt regarding legal and license information.
//---------------------------------------------------------------------------------------

#include <PDF/PDFNet.h>
#include <PDF/PDFDoc.h>
#include <PDF/ElementBuilder.h>
#include <PDF/ElementReader.h>
#include <PDF/ElementWriter.h>
#include <PDF/Annot.h>
#include <SDF/Obj.h>
#include <iostream>
#include "../../LicenseKey/CPP/LicenseKey.h"

using namespace pdftron;
using namespace SDF;
using namespace PDF;
using namespace std;


std::string output_path = "../../TestFiles/Output/";
std::string input_path = "../../TestFiles/";

void AnnotationHighLevelAPI(PDFDoc& doc)
{
	// The following code snippet traverses all annotations in the document
	cout << "Traversing all annotations in the document..." << endl; 

	UString uri;
	int page_num=1;
	for (PageIterator itr = doc.GetPageIterator(); itr.HasNext(); itr.Next()) 
	{
		cout << "Page " << page_num++ << ": " << endl; 

		Page page = itr.Current();
		int num_annots = page.GetNumAnnots(); 
		for (int i=0; i<num_annots; ++i) 
		{
			Annot annot = page.GetAnnot(i);
			if (!annot.IsValid()) continue;
			cout << "Annot Type: " << annot.GetSDFObj().Get("Subtype").Value().GetName() << endl; 

			Rect bbox = annot.GetRect();
			cout << "  Position: " << bbox.x1 
				<< ", " << bbox.y1
				<< ", " << bbox.x2
				<< ", " << bbox.y2 << endl;

			switch (annot.GetType()) 
			{
			case Annot::e_Link: 
				{
					Annots::Link link(annot);
					Action action = link.GetAction();
					if (!action.IsValid()) continue;
					if (action.GetType() == Action::e_GoTo) 
					{
						Destination dest = action.GetDest();
						if (!dest.IsValid()) {
							cout << "  Destination is not valid" << endl;
						}
						else {
							int page_num = dest.GetPage().GetIndex();
							cout << "  Links to: page number " << page_num << " in this document" << endl;
						}
					}
					else if (action.GetType() == Action::e_URI) 
					{						
						action.GetSDFObj().Get("URI").Value().GetAsPDFText(uri);
						cout << "  Links to: " << uri << endl;
					}
					// ...
				}
				break; 
			case Annot::e_Widget:
				break; 
			case Annot::e_FileAttachment:
				break; 
				// ...
			default:
				break; 
			}
		}
	}

	// Use the high-level API to create new annotations.
	Page first_page = doc.GetPage(1);

	// Create a hyperlink...
	Annots::Link hyperlink = Annots::Link::Create(doc, Rect(85, 570, 503, 524), Action::CreateURI(doc, "http://www.pdftron.com"));
	first_page.AnnotPushBack(hyperlink);

	// Create an intra-document link...
	Action goto_page_3 = Action::CreateGoto(Destination::CreateFitH(doc.GetPage(3), 0));
	Annots::Link link = Annots::Link::Create(doc, Rect(85, 458, 503, 502), goto_page_3);
	link.SetColor(ColorPt(0, 0, 1));

	// Add the new annotation to the first page
	first_page.AnnotPushBack(link);

	// Create a stamp annotation ...
	Annots::RubberStamp stamp = Annots::RubberStamp::Create(doc, Rect(30, 30, 300, 200));
	stamp.SetIcon("Draft");
	first_page.AnnotPushBack(stamp);

	// Create a file attachment annotation (embed the 'peppers.jpg').
	Annots::FileAttachment file_attach = Annots::FileAttachment::Create(doc, Rect(80, 280, 108, 320), (input_path + "peppers.jpg").c_str());
	first_page.AnnotPushBack(file_attach);


	Annots::Ink ink = Annots::Ink::Create(doc, Rect(110, 10, 300, 200));
	Point pt3(110, 10);
	//pt3.x = 110; pt3.y = 10;
	ink.SetPoint(0, 0, pt3);
	pt3.x = 150; pt3.y = 50;
	ink.SetPoint(0, 1, pt3);
	pt3.x = 190; pt3.y = 60;
	ink.SetPoint(0, 2, pt3);
	pt3.x = 180; pt3.y = 90;
	ink.SetPoint(1, 0, pt3);
	pt3.x = 190; pt3.y = 95;
	ink.SetPoint(1, 1, pt3);
	pt3.x = 200; pt3.y = 100;
	ink.SetPoint(1, 2, pt3);
	pt3.x = 166; pt3.y = 86;
	ink.SetPoint(2, 0, pt3);
	pt3.x = 196; pt3.y = 96;
	ink.SetPoint(2, 1, pt3);
	pt3.x = 221; pt3.y = 121;
	ink.SetPoint(2, 2, pt3);
	pt3.x = 288; pt3.y = 188;
	ink.SetPoint(2, 3, pt3);
	ink.SetColor(ColorPt(0, 1, 1), 3);
	first_page.AnnotPushBack(ink);

}

void AnnotationLowLevelAPI(PDFDoc& doc)  
{
	Page page = (doc.GetPageIterator()).Current(); 

	Obj annots = page.GetAnnots();

	if (!annots) 
	{
		// If there are no annotations, create a new annotation 
		// array for the page.
		annots = doc.CreateIndirectArray();  
		page.GetSDFObj().Put("Annots", annots);
	}

	// Create a Text annotation
	Obj annot = doc.CreateIndirectDict();
	annot.PutName("Subtype", "Text");
	annot.PutBool("Open", true);
	annot.PutString("Contents", "The quick brown fox ate the lazy mouse.");
	annot.PutRect("Rect", 266, 116, 430, 204);

	// Insert the annotation in the page annotation array
	annots.PushBack(annot);	

	// Create a Link annotation
	Obj link1 = doc.CreateIndirectDict();
	link1.PutName("Subtype", "Link");
	Destination	dest = Destination::CreateFit(doc.GetPage(2));
	link1.Put("Dest", dest.GetSDFObj());
	link1.PutRect("Rect", 85, 705, 503, 661);
	annots.PushBack(link1);

	// Create another Link annotation
	Obj link2 = doc.CreateIndirectDict();
	link2.PutName("Subtype", "Link");
	Destination	dest2 = Destination::CreateFit(doc.GetPage(3));
	link2.Put("Dest", dest2.GetSDFObj());
	link2.PutRect("Rect", 85, 638, 503, 594);
	annots.PushBack(link2);

	// Note that PDFNet API can be used to modify existing annotations. 
	// In the following example we will modify the second link annotation 
	// (link2) so that it points to the 10th page. We also use a different 
	// destination page fit type.

	// link2 = annots.GetAt(annots.Size()-1);
	link2.Put("Dest", 
		Destination::CreateXYZ(doc.GetPage(10), 100, 792-70, 10).GetSDFObj());

	// Create a third link annotation with a hyperlink action (all other 
	// annotation types can be created in a similar way)
	Obj link3 = doc.CreateIndirectDict();
	link3.PutName("Subtype", "Link");
	link3.PutRect("Rect", 85, 570, 503, 524);

	// Create a URI action 
	Obj action = link3.PutDict("A");
	action.PutName("S", "URI");
	action.PutString("URI", "http://www.pdftron.com");

	annots.PushBack(link3);
}


void CreateTestAnnots(PDFDoc& doc) {
	using namespace pdftron;
	using namespace SDF;
	using namespace PDF;
	using namespace Annots;


	ElementWriter ew;
	ElementBuilder eb;
	Element element ;

	Page first_page= doc.PageCreate(Rect(0, 0, 600, 600));
	doc.PagePushBack(first_page);
	ew.Begin(first_page, ElementWriter::e_overlay, false );	// begin writing to this page
	ew.End();  // save changes to the current page

	//
	// Test of a free text annotation.
	//
	{
		Annots::FreeText txtannot = Annots::FreeText::Create( doc, Rect(10, 400, 160, 570)  );
		txtannot.SetContents( UString("\n\nSome swift brown fox snatched a gray hare out of the air by freezing it with an angry glare."
							  "\n\nAha!\n\nAnd there was much rejoicing!"	) );
		//std::vector<double> dash( 2, 2.0 );
		txtannot.SetBorderStyle( Annot::BorderStyle( Annot::BorderStyle::e_solid, 1, 10, 20 ), false);
		txtannot.SetQuaddingFormat(0);
		first_page.AnnotPushBack(txtannot);
		txtannot.RefreshAppearance();
	}
	{
		Annots::FreeText txtannot = Annots::FreeText::Create( doc, Rect(100, 100, 350, 500)  );
		txtannot.SetContentRect( Rect( 200, 200, 350, 500 ) );
		txtannot.SetContents( UString("\n\nSome swift brown fox snatched a gray hare out of the air by freezing it with an angry glare."
							  "\n\nAha!\n\nAnd there was much rejoicing!"	) );
		txtannot.SetCalloutLinePoints( Point(200,300), Point(150,290), Point(110,110) );
		//std::vector<double> dash( 2, 2.0 );
		txtannot.SetBorderStyle( Annot::BorderStyle( Annot::BorderStyle::e_solid, 1, 10, 20 ), false);
		txtannot.SetEndingStyle( Line::e_ClosedArrow );
		txtannot.SetColor( ColorPt( 0, 1, 0 ) );
		txtannot.SetQuaddingFormat(1);
		first_page.AnnotPushBack(txtannot);
		txtannot.RefreshAppearance();
	}
	{
		Annots::FreeText txtannot = Annots::FreeText::Create( doc, Rect(400, 10, 550, 400)  );
		txtannot.SetContents( UString("\n\nSome swift brown fox snatched a gray hare out of the air by freezing it with an angry glare."
							  "\n\nAha!\n\nAnd there was much rejoicing!"	) );
		txtannot.SetBorderStyle( Annot::BorderStyle( Annot::BorderStyle::e_solid, 1, 10, 20 ), false);
		txtannot.SetColor( ColorPt( 0, 0, 1 ) );
		txtannot.SetOpacity( 0.2 );
		txtannot.SetQuaddingFormat(2);
		first_page.AnnotPushBack(txtannot);
		txtannot.RefreshAppearance();
	}

	Page page= doc.PageCreate(Rect(0, 0, 600, 600));
	doc.PagePushBack(page);
	ew.Begin(page, ElementWriter::e_overlay, false );	// begin writing to this page
	eb.Reset();			// Reset the GState to default
	ew.End();  // save changes to the current page

	{
		//Create a Line annotation...
		Line line=Line::Create(doc, Rect(250, 250, 400, 400));
		line.SetStartPoint( Point(350, 270 ) );
		line.SetEndPoint( Point(260,370) );
		line.SetStartStyle(Line::e_Square);
		line.SetEndStyle(Line::e_Circle);
		line.SetColor(ColorPt(.3, .5, 0), 3);
		line.SetContents( UString("Dashed Captioned") );
		line.SetShowCaption(true);
		line.SetCaptionPosition( Line::e_Top );
		std::vector<double> dash( 2, 2.0 );
		line.SetBorderStyle( Annot::BorderStyle( Annot::BorderStyle::e_dashed, 2, 0, 0, dash ) );
		line.RefreshAppearance();
		page.AnnotPushBack(line);
	}
	{
		Line line=Line::Create(doc, Rect(347, 377, 600, 600));
		line.SetStartPoint( Point(385, 410 ) );
		line.SetEndPoint( Point(540,555) );
		line.SetStartStyle(Line::e_Circle);
		line.SetEndStyle(Line::e_OpenArrow);
		line.SetColor(ColorPt(1, 0, 0), 3);
		line.SetInteriorColor(ColorPt(0, 1, 0), 3);
		line.SetContents( UString("Inline Caption") );
		line.SetShowCaption(true);
		line.SetCaptionPosition( Line::e_Inline );
		line.SetLeaderLineExtensionLength( 4. );
		line.SetLeaderLineLength( -12. );
		line.SetLeaderLineOffset( 2. );
		line.RefreshAppearance();
		page.AnnotPushBack(line);
	}
	{
		Line line=Line::Create(doc, Rect(10, 400, 200, 600));
		line.SetStartPoint( Point(25, 426 ) );
		line.SetEndPoint( Point(180,555) );
		line.SetStartStyle(Line::e_Circle);
		line.SetEndStyle(Line::e_Square);
		line.SetColor(ColorPt(0, 0, 1), 3);
		line.SetInteriorColor(ColorPt(1, 0, 0), 3);
		line.SetContents( UString("Offset Caption") );
		line.SetShowCaption(true);
		line.SetCaptionPosition( Line::e_Top );
		line.SetTextHOffset( -60 );
		line.SetTextVOffset( 10 );
		line.RefreshAppearance();
		page.AnnotPushBack(line);
	}
	{
		Line line=Line::Create(doc, Rect(200, 10, 400, 70));
		line.SetStartPoint( Point(220, 25 ) );
		line.SetEndPoint( Point(370,60) );
		line.SetStartStyle(Line::e_Butt);
		line.SetEndStyle(Line::e_OpenArrow);
		line.SetColor(ColorPt(0, 0, 1), 3);
		line.SetContents( UString("Regular Caption") );
		line.SetShowCaption(true);
		line.SetCaptionPosition( Line::e_Top );
		line.RefreshAppearance();
		page.AnnotPushBack(line);
	}
	{
		Line line=Line::Create(doc, Rect(200, 70, 400, 130));
		line.SetStartPoint( Point(220, 111 ) );
		line.SetEndPoint( Point(370,78) );
		line.SetStartStyle(Line::e_Circle);
		line.SetEndStyle(Line::e_Diamond);
		line.SetContents( UString("Circle to Diamond") );
		line.SetColor(ColorPt(0, 0, 1), 3);
		line.SetInteriorColor(ColorPt(0, 1, 0), 3);
		line.SetShowCaption(true);
		line.SetCaptionPosition( Line::e_Top );
		line.RefreshAppearance();
		page.AnnotPushBack(line);
	}
	{
		Line line=Line::Create(doc, Rect(10, 100, 160, 200));
		line.SetStartPoint( Point(15, 110 ) );
		line.SetEndPoint( Point(150, 190) );
		line.SetStartStyle(Line::e_Slash);
		line.SetEndStyle(Line::e_ClosedArrow);
		line.SetContents( UString("Slash to CArrow") );
		line.SetColor(ColorPt(1, 0, 0), 3);
		line.SetInteriorColor(ColorPt(0, 1, 1), 3);
		line.SetShowCaption(true);
		line.SetCaptionPosition( Line::e_Top );
		line.RefreshAppearance();
		page.AnnotPushBack(line);
	}
	{
		Line line=Line::Create(doc, Rect( 270, 270, 570, 433 ));
		line.SetStartPoint( Point(300, 400 ) );
		line.SetEndPoint( Point(550, 300) );
		line.SetStartStyle(Line::e_RClosedArrow);
		line.SetEndStyle(Line::e_ROpenArrow);
		line.SetContents( UString("ROpen & RClosed arrows") );
		line.SetColor(ColorPt(0, 0, 1), 3);
		line.SetInteriorColor(ColorPt(0, 1, 0), 3);
		line.SetShowCaption(true);
		line.SetCaptionPosition( Line::e_Top );
		line.RefreshAppearance();
		page.AnnotPushBack(line);
	}
	{
		Line line=Line::Create(doc, Rect( 195, 395, 205, 505 ));
		line.SetStartPoint( Point(200, 400 ) );
		line.SetEndPoint( Point(200, 500) );
		line.RefreshAppearance();
		page.AnnotPushBack(line);
	}
	{
		Line line=Line::Create(doc, Rect( 55, 299, 150, 301 ));
		line.SetStartPoint( Point(55, 300 ) );
		line.SetEndPoint( Point(155, 300) );
		line.SetStartStyle(Line::e_Circle);
		line.SetEndStyle(Line::e_Circle);
		line.SetContents( UString("Caption that's longer than its line.") );
		line.SetColor(ColorPt(1, 0, 1), 3);
		line.SetInteriorColor(ColorPt(0, 1, 0), 3);
		line.SetShowCaption(true);
		line.SetCaptionPosition( Line::e_Top );
		line.RefreshAppearance();
		page.AnnotPushBack(line);
	}
	{
		Line line=Line::Create(doc, Rect( 300, 200, 390, 234 ));
		line.SetStartPoint( Point(310, 210 ) );
		line.SetEndPoint( Point(380, 220) );
		line.SetColor(ColorPt(0, 0, 0), 3);
		line.RefreshAppearance();
		page.AnnotPushBack(line);
	}

	Page page3 = doc.PageCreate(Rect(0, 0, 600, 600));
	ew.Begin(page3);	// begin writing to the page
	ew.End();  // save changes to the current page
	doc.PagePushBack(page3);
	{
		Circle circle=Circle::Create(doc, Rect( 300, 300, 390, 350 ));
		circle.SetColor(ColorPt(0, 0, 0), 3);
		circle.RefreshAppearance();
		page3.AnnotPushBack(circle);
	}
	{
		Circle circle=Circle::Create(doc, Rect( 100, 100, 200, 200 ));
		circle.SetColor(ColorPt(0, 1, 0), 3);
		circle.SetInteriorColor(ColorPt(0, 0, 1), 3);
		std::vector<double> dash( 2 ); dash[0]=2;dash[1]=4;
		circle.SetBorderStyle( Annot::BorderStyle( Annot::BorderStyle::e_dashed, 3, 0, 0, dash ) );
		circle.SetPadding( 2 );
		circle.RefreshAppearance();
		page3.AnnotPushBack(circle);
	}
	{
		Square sq = Square::Create( doc, Rect(10,200, 80, 300 ) );
		sq.SetColor(ColorPt(0, 0, 0), 3);
		sq.RefreshAppearance();
		page3.AnnotPushBack( sq );
	}
	{
		Square sq = Square::Create( doc, Rect(500,200, 580, 300 ) );
		sq.SetColor(ColorPt(1, 0, 0), 3);
		sq.SetInteriorColor(ColorPt(0, 1, 1), 3);
		std::vector<double> dash( 2 ); dash[0]=4;dash[1]=2;
		sq.SetBorderStyle( Annot::BorderStyle( Annot::BorderStyle::e_dashed, 6, 0, 0, dash ) );
		sq.SetPadding( 4 );
		sq.RefreshAppearance();
		page3.AnnotPushBack( sq );
	}
	{
		Polygon poly = Polygon::Create(doc, Rect(5, 500, 125, 590));
		poly.SetColor(ColorPt(1, 0, 0), 3);
		poly.SetInteriorColor(ColorPt(1, 1, 0), 3);
		poly.SetVertex(0, Point(12,510) );
		poly.SetVertex(1, Point(100,510) );
		poly.SetVertex(2, Point(100,555) );
		poly.SetVertex(3, Point(35,544) );
		poly.SetBorderStyle( Annot::BorderStyle( Annot::BorderStyle::e_solid, 4, 0, 0 ) );
		poly.SetPadding( 4 );
		poly.RefreshAppearance();
		page3.AnnotPushBack( poly );
	}
	{
		PolyLine poly = PolyLine::Create(doc, Rect(400, 10, 500, 90));
		poly.SetColor(ColorPt(1, 0, 0), 3);
		poly.SetInteriorColor(ColorPt(0, 1, 0), 3);
		poly.SetVertex(0, Point(405,20) );
		poly.SetVertex(1, Point(440,40) );
		poly.SetVertex(2, Point(410,60) );
		poly.SetVertex(3, Point(470,80) );
		poly.SetBorderStyle( Annot::BorderStyle( Annot::BorderStyle::e_solid, 2, 0, 0 ) );
		poly.SetPadding( 4 );
		poly.SetStartStyle( Line::e_RClosedArrow );
		poly.SetEndStyle( Line::e_ClosedArrow );
		poly.RefreshAppearance();
		page3.AnnotPushBack( poly );
	}
	{
		Link lk = Link::Create( doc, Rect(5,5,55,24) );
		//lk.SetColor( ColorPt(0,1,0), 3 );
		lk.RefreshAppearance();
		page3.AnnotPushBack( lk );
	}


	Page page4 = doc.PageCreate(Rect(0, 0, 600, 600));
	ew.Begin(page4);	// begin writing to the page
	ew.End();  // save changes to the current page
	doc.PagePushBack(page4);

	{	
		ew.Begin( page4 );
		Font font = Font::Create(doc, Font::e_helvetica);
		element = eb.CreateTextBegin( font, 16 );
		element.SetPathFill(true);
		ew.WriteElement(element);
		element = eb.CreateTextRun( "Some random text on the page", font, 16 );
		element.SetTextMatrix(1, 0, 0, 1, 100, 500 );
		ew.WriteElement(element);
		ew.WriteElement( eb.CreateTextEnd() );
		ew.End();
	}
	{
		Highlight hl = Highlight::Create( doc, Rect(100,490,150,515) );
		hl.SetColor( ColorPt(0,1,0), 3 );
		hl.RefreshAppearance();
		page4.AnnotPushBack( hl );
	}
	{
		Squiggly sq = Squiggly::Create( doc, Rect(100,450,250,600) );
		//sq.SetColor( ColorPt(1,0,0), 3 );
		sq.SetQuadPoint( 0, QuadPoint( Point( 122,455), Point(240, 545), Point(230, 595), Point(101,500 ) ) );
		sq.RefreshAppearance();
		page4.AnnotPushBack( sq );
	}
	{
		Caret cr = Caret::Create( doc, Rect(100,40,129,69) );
		cr.SetColor( ColorPt(0,0,1), 3 );
		cr.SetSymbol( "P" );
		cr.RefreshAppearance();
		page4.AnnotPushBack( cr );
	}


	Page page5 = doc.PageCreate(Rect(0, 0, 600, 600));
	ew.Begin(page5);	// begin writing to the page
	ew.End();  // save changes to the current page
	doc.PagePushBack(page5);
	FileSpec fs = FileSpec::Create( doc, (input_path + "butterfly.png").c_str(), false );
	Page page6 = doc.PageCreate(Rect(0, 0, 600, 600));
	ew.Begin(page6);	// begin writing to the page
	ew.End();  // save changes to the current page
	doc.PagePushBack(page6);

	{
		Text txt = Text::Create( doc, Rect( 10, 20, 30, 40 ) );
		txt.SetIcon( "UserIcon" );
		txt.SetContents( "User defined icon, unrecognized by appearance generator" );
		txt.SetColor( ColorPt(0,1,0) );
		txt.RefreshAppearance();
		page6.AnnotPushBack( txt );
	}
	{
		Ink ink = Ink::Create( doc, Rect( 100, 400, 200, 550 ) );
		ink.SetColor( ColorPt(0,0,1) );
		ink.SetPoint( 1, 3, Point( 220, 505) );
		ink.SetPoint( 1, 0, Point( 100, 490) );
		ink.SetPoint( 0, 1, Point( 120, 410) );
		ink.SetPoint( 0, 0, Point( 100, 400) );
		ink.SetPoint( 1, 2, Point( 180, 490) );
		ink.SetPoint( 1, 1, Point( 140, 440) );		
		ink.SetBorderStyle( Annot::BorderStyle( Annot::BorderStyle::e_solid, 3, 0, 0  ) );
		ink.RefreshAppearance();
		page6.AnnotPushBack( ink );
	}


	Page page7 = doc.PageCreate(Rect(0, 0, 600, 600));
	ew.Begin(page7);	// begin writing to the page
	ew.End();  // save changes to the current page
	doc.PagePushBack(page7);

	{
		Sound snd = Sound::Create( doc, Rect( 100, 500, 120, 520 ) );
		snd.SetColor(  ColorPt(1,1,0) );
		snd.SetIcon( Sound::e_Speaker );
		snd.RefreshAppearance();
		page7.AnnotPushBack( snd );
	}
	{
		Sound snd = Sound::Create( doc, Rect( 200, 500, 220, 520 ) );
		snd.SetColor(  ColorPt(1,1,0) );
		snd.SetIcon( Sound::e_Mic );
		snd.RefreshAppearance();
		page7.AnnotPushBack( snd );
	}




	Page page8 = doc.PageCreate(Rect(0, 0, 600, 600));
	ew.Begin(page8);	// begin writing to the page
	ew.End();  // save changes to the current page
	doc.PagePushBack(page8);

	for( int ipage =0; ipage < 2; ++ipage ) {
		double px = 5, py = 520;
		for( RubberStamp::Icon istamp = RubberStamp::e_Approved; 
			istamp <= RubberStamp::e_Draft; 
			istamp = static_cast<RubberStamp::Icon>(  static_cast<int>(istamp) + 1  ) ) {
				RubberStamp st = RubberStamp::Create( doc, Rect(1,1,100,100) );
				st.SetIcon( istamp );
				st.SetContents( UString( st.GetIconName() ) );
				st.SetRect( Rect(px, py, px+100, py+25 ) );
				py -= 100;
				if( py < 0 ) {
					py = 520;
					px += 200;
				}
				if( ipage == 0 )
					//page7.AnnotPushBack( st );
					;
				else {
					page8.AnnotPushBack( st );
					st.RefreshAppearance();
				}
		}
	}
	RubberStamp st = RubberStamp::Create( doc, Rect(400,5,550,45) );
	st.SetIcon( "UserStamp" );
	st.SetContents( "User defined stamp" );
	page8.AnnotPushBack( st );
	st.RefreshAppearance();



}




int main(int argc, char *argv[])
{
	int ret = 0;
	PDFNet::Initialize(LicenseKey);

	std::string output_path = "../../TestFiles/Output/";

	try  
	{
		PDFDoc doc((input_path + "numbered.pdf").c_str());
		doc.InitSecurityHandler();

		// An example of using SDF/Cos API to add any type of annotations.
		AnnotationLowLevelAPI(doc);
		doc.Save((output_path + "annotation_test1.pdf").c_str(), SDFDoc::e_linearized, 0);
		cout << "Done. Results saved in annotation_test1.pdf" << endl;

		// An example of using the high-level PDFNet API to read existing annotations,
		// to edit existing annotations, and to create new annotation from scratch.
		AnnotationHighLevelAPI(doc);
		doc.Save((output_path + "annotation_test2.pdf").c_str(), SDFDoc::e_linearized, 0);
		cout << "Done. Results saved in annotation_test2.pdf" << endl;

		// an example of creating various annotations in a brand new document
		PDFDoc doc1;
		CreateTestAnnots( doc1 );
		doc1.Save(output_path + "new_annot_test_api.pdf", SDFDoc::e_linearized, 0);
		cout << "Saved new_annot_test_api.pdf" << std::endl;
	}
	catch(Common::Exception& e)
	{
		cout << e << std::endl;
		ret = 1;
	}
	catch(...)
	{
		cout << "Unknown Exception" << std::endl;
		ret = 1;
	}

	PDFNet::Terminate();
	return ret;
}
```

{% endcode %}
{% endtab %}

{% tab title="Go" %}
{% code lineNumbers="true" %}

```go
//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2021 by PDFTron Systems Inc. All Rights Reserved.
// Consult LICENSE.txt regarding license information.
//---------------------------------------------------------------------------------------

package main
import (
	"fmt"
	"strconv"
	. "pdftron"
)

import  "pdftron/Samples/LicenseKey/GO"

// Relative path to the folder containing the test files.
var inputPath = "../../TestFiles/"
var outputPath = "../../TestFiles/Output/"

func AnnotationLowLevelAPI(doc PDFDoc){
    itr := doc.GetPageIterator()
    page := itr.Current()
    annots := page.GetAnnots()
    if (page.GetNumAnnots() == 0){
        // If there are no annotations, create a new annotation 
        // array for the page.
        annots = doc.CreateIndirectArray()
        page.GetSDFObj().Put("Annots", annots)
	}

    // Create a Text annotation
    annot := doc.CreateIndirectDict()
    annot.PutName("Subtype", "Text")
    annot.PutBool("Open", true)
    annot.PutString("Contents", "The quick brown fox ate the lazy mouse.")
    annot.PutRect("Rect", 266.0, 116.0, 430.0, 204.0)

    // Insert the annotation in the page annotation array
    annots.PushBack(annot)   
   
    // Create a Link annotation
    link1 := doc.CreateIndirectDict()
    link1.PutName("Subtype", "Link")
    dest := DestinationCreateFit(doc.GetPage(2))
    link1.Put("Dest", dest.GetSDFObj())
    link1.PutRect("Rect", 85.0, 705.0, 503.0, 661.0)
    annots.PushBack(link1)

    // Create another Link annotation
    link2 := doc.CreateIndirectDict()
    link2.PutName("Subtype", "Link")
    dest2 := DestinationCreateFit((doc.GetPage(3)))
    link2.Put("Dest", dest2.GetSDFObj())
    link2.PutRect("Rect", 85.0, 638.0, 503.0, 594.0)
    annots.PushBack(link2)
    
    // Note that PDFNet APi can be used to modify existing annotations. 
    // In the following example we will modify the second link annotation 
    // (link2) so that it points to the 10th page. We also use a different 
    // destination page fit type.
    
    // link2 = annots.GetAt(annots.Size()-1)
    link2.Put("Dest", DestinationCreateXYZ(doc.GetPage(10), 100, 792-70, 10).GetSDFObj())
    
    // Create a third link annotation with a hyperlink action (all other 
    // annotation types can be created in a similar way)
    link3 := doc.CreateIndirectDict()
    link3.PutName("Subtype", "Link")
    link3.PutRect("Rect", 85.0, 570.0, 503.0, 524.0)
    
    // Create a URI action 
    action := link3.PutDict("A")
    action.PutName("S", "URI")
    action.PutString("URI", "http://www.pdftron.com")
    
    annots.PushBack(link3)
}

func AnnotationHighLevelAPI(doc PDFDoc){
    // The following code snippet traverses all annotations in the document
    fmt.Println("Traversing all annotations in the document...")
    pageNum := 1
    itr := doc.GetPageIterator()
    
    for itr.HasNext(){
        fmt.Println("Page " + strconv.Itoa(pageNum) + ": ")
        pageNum = pageNum + 1
        page := itr.Current()
        numAnnots := page.GetNumAnnots()
        i := uint(0)
        for i < numAnnots{
            annot := page.GetAnnot(i)
            if (!annot.IsValid()){
                continue
			}
            fmt.Println("Annot Type: " + annot.GetSDFObj().Get("Subtype").Value().GetName())
            
            bbox := annot.GetRect()
            fmt.Println("  Position: " + fmt.Sprintf("%.0f", bbox.GetX1()) + 
						", " + fmt.Sprintf("%.0f", bbox.GetY1()) + 
						", " + fmt.Sprintf("%.0f", bbox.GetX2()) + 
						", " + fmt.Sprintf("%.0f", bbox.GetY2()))
            
            atype := annot.GetType()
            
            if (atype == AnnotE_Link){
                link := NewLink(annot)
                action := link.GetAction()
                if (!action.IsValid()){
                    continue
				}
                if (action.GetType() == ActionE_GoTo){
                    dest := action.GetDest()
                    if (!dest.IsValid()){
                        fmt.Println("  Destination is not valid.")
					}else{
                        pageN := dest.GetPage().GetIndex()
                        fmt.Println("  Links to: page number " + strconv.Itoa(pageN) + " in this document")
					}
				}else if (action.GetType() == ActionE_URI){
                    uri := action.GetSDFObj().Get("URI").Value().GetAsPDFText()
                    fmt.Println("  Links to: " + uri)
				}
            }else if (atype == AnnotE_Widget){
                //handle Widget here
			}else if (atype == AnnotE_FileAttachment){
                //handle FileAttachment here
			}
            i = i + 1
		}
        itr.Next()
	}
    // Use the high-level API to create new annotations.        
    firstPage := doc.GetPage(1)
    
    // Create a hyperlink...
    hyperlink := LinkCreate(doc.GetSDFDoc(), NewRect(85.0, 570.0, 503.0, 524.0), ActionCreateURI(doc.GetSDFDoc(), "http://www.pdftron.com"))
    firstPage.AnnotPushBack(hyperlink)
    
    // Create an intra-document link...
    gotoPage3 := ActionCreateGoto(DestinationCreateFitH(doc.GetPage(3), 0))
    link := LinkCreate(doc.GetSDFDoc(), NewRect(85.0, 458.0, 503.0, 502.0), gotoPage3)
    link.SetColor(NewColorPt(0.0, 0.0, 1.0))
    
    // Add the new annotation to the first page
    firstPage.AnnotPushBack(link) 
    
    // Create a stamp annotation ...
    stamp := RubberStampCreate(doc.GetSDFDoc(), NewRect(30.0, 30.0, 300.0, 200.0))
    stamp.SetIcon("Draft")
    firstPage.AnnotPushBack(stamp)
    
    // Create a file attachment annotation (embed the 'peppers.jpg').
    file_attach := FileAttachmentCreate(doc.GetSDFDoc(), NewRect(80.0, 280.0, 108.0, 320.0), (inputPath + "peppers.jpg"))
    firstPage.AnnotPushBack(file_attach)


    ink := InkCreate(doc.GetSDFDoc(), NewRect(110.0, 10.0, 300.0, 200.0))
    pt3 := NewPoint(110.0, 10.0)
    pt3.SetX(110)
    pt3.SetY(10)
    ink.SetPoint(0, 0, pt3)
    pt3.SetX(150) 
    pt3.SetY(50)
    ink.SetPoint(0, 1, pt3)
    pt3.SetX(190) 
    pt3.SetY(60)
    ink.SetPoint(0, 2, pt3)
    pt3.SetX(180) 
    pt3.SetY(90)
    ink.SetPoint(1, 0, pt3)
    pt3.SetX(190) 
    pt3.SetY(95)
    ink.SetPoint(1, 1, pt3)
    pt3.SetX(200) 
    pt3.SetY(100)
    ink.SetPoint(1, 2, pt3)
    pt3.SetX(166) 
    pt3.SetY(86)
    ink.SetPoint(2, 0, pt3)
    pt3.SetX(196) 
    pt3.SetY(96)
    ink.SetPoint(2, 1, pt3)
    pt3.SetX(221) 
    pt3.SetY(121)
    ink.SetPoint(2, 2, pt3)
    pt3.SetX(288) 
    pt3.SetY(188)
    ink.SetPoint(2, 3, pt3)
    ink.SetColor(NewColorPt(0.0, 1.0, 1.0), 3)
    firstPage.AnnotPushBack(ink)
}

func CreateTestAnnots(doc PDFDoc){
    ew := NewElementWriter()
    eb := NewElementBuilder()
    
    firstPage := doc.PageCreate(NewRect(0.0, 0.0, 600.0, 600.0))
    doc.PagePushBack(firstPage)
    ew.Begin(firstPage, ElementWriterE_overlay, false )   // begin writing to this page
    ew.End()    // save changes to the current page
    
    // Test of a free text annotation.
    txtannot := FreeTextCreate( doc.GetSDFDoc(), NewRect(10.0, 400.0, 160.0, 570.0)  )
    txtannot.SetContents( "\n\nSome swift brown fox snatched a gray hare out " +
                          "of the air by freezing it with an angry glare." +
                          "\n\nAha!\n\nAnd there was much rejoicing!"    )
    txtannot.SetBorderStyle( NewBorderStyle( BorderStyleE_solid, 1.0, 10.0, 20.0 ), false )
    txtannot.SetQuaddingFormat(0)
    firstPage.AnnotPushBack(txtannot)
    txtannot.RefreshAppearance()
    
    txtannot = FreeTextCreate( doc.GetSDFDoc(), NewRect(100.0, 100.0, 350.0, 500.0)  )
    txtannot.SetContentRect( NewRect(200.0, 200.0, 350.0, 500.0 ) )
    txtannot.SetContents( "\n\nSome swift brown fox snatched a gray hare out of the air " +
                            "by freezing it with an angry glare." +
                            "\n\nAha!\n\nAnd there was much rejoicing!"    )
    txtannot.SetCalloutLinePoints( NewPoint(200.0,300.0), NewPoint(150.0,290.0), NewPoint(110.0,110.0) )
    txtannot.SetBorderStyle( NewBorderStyle( BorderStyleE_solid, 1.0, 10.0, 20.0 ), false )
    txtannot.SetEndingStyle( LineAnnotE_ClosedArrow )
    txtannot.SetColor( NewColorPt( 0.0, 1.0, 0.0 ) )
    txtannot.SetQuaddingFormat(1)
    firstPage.AnnotPushBack(txtannot)
    txtannot.RefreshAppearance()
    
    txtannot = FreeTextCreate( doc.GetSDFDoc(), NewRect(400.0, 10.0, 550.0, 400.0) )    
    txtannot.SetContents( "\n\nSome swift brown fox snatched a gray hare out of the air " +
                          "by freezing it with an angry glare." +
                          "\n\nAha!\n\nAnd there was much rejoicing!"    )
    txtannot.SetBorderStyle( NewBorderStyle( BorderStyleE_solid, 1.0, 10.0, 20.0 ), false )
    txtannot.SetColor( NewColorPt( 0.0, 0.0, 1.0 ) )
    txtannot.SetOpacity( 0.2 )
    txtannot.SetQuaddingFormat(2)
    firstPage.AnnotPushBack(txtannot)
    txtannot.RefreshAppearance()
    
    page := doc.PageCreate(NewRect(0.0, 0.0, 600.0, 600.0))
    doc.PagePushBack(page)
    ew.Begin(page, ElementWriterE_overlay, false )    // begin writing to this page
    eb.Reset() // Reset the GState to default
    ew.End()    // save changes to the current page
    
    // Create a Line annotation...
    line := LineAnnotCreate(doc.GetSDFDoc(), NewRect(250.0, 250.0, 400.0, 400.0))
    line.SetStartPoint( NewPoint(350.0, 270.0 ) )
    line.SetEndPoint( NewPoint(260.0,370.0) )
    line.SetStartStyle(LineAnnotE_Square)
    line.SetEndStyle(LineAnnotE_Circle)
    line.SetColor(NewColorPt(.3, .5, 0.0), 3)
    line.SetContents( "Dashed Captioned" )
    line.SetShowCaption(true)
    line.SetCaptionPosition( &LineAnnotE_Top )
	var dash = NewVectorDouble()
	dash.Add(2.0)
	dash.Add(2.0)
    line.SetBorderStyle( NewBorderStyle( BorderStyleE_dashed, 2.0, 0.0, 0.0, dash ) )
	dash.Clear()
    line.RefreshAppearance()
    page.AnnotPushBack(line)
    
    line = LineAnnotCreate(doc.GetSDFDoc(), NewRect(347.0, 377.0, 600.0, 600.0))
    line.SetStartPoint( NewPoint(385.0, 410.0 ) )
    line.SetEndPoint( NewPoint(540.0,555.0) )
    line.SetStartStyle(LineAnnotE_Circle)
    line.SetEndStyle(LineAnnotE_OpenArrow)
    line.SetColor(NewColorPt(1.0, 0.0, 0.0), 3)
    line.SetInteriorColor(NewColorPt(0.0, 1.0, 0.0), 3)
    line.SetContents( "Inline Caption" )
    line.SetShowCaption(true)
    line.SetCaptionPosition( &LineAnnotE_Inline )
    line.SetLeaderLineExtensionLength( -4. )
    line.SetLeaderLineLength( -12. )
    line.SetLeaderLineOffset( 2. )
    line.RefreshAppearance()
    page.AnnotPushBack(line)
    
    line = LineAnnotCreate(doc.GetSDFDoc(), NewRect(10.0, 400.0, 200.0, 600.0))
    line.SetStartPoint( NewPoint(25.0, 426.0 ) )
    line.SetEndPoint( NewPoint(180.0,555.0) )
    line.SetStartStyle(LineAnnotE_Circle)
    line.SetEndStyle(LineAnnotE_Square)
    line.SetColor(NewColorPt(0.0, 0.0, 1.0), 3)
    line.SetInteriorColor(NewColorPt(1.0, 0.0, 0.0), 3)
    line.SetContents("Offset Caption")
    line.SetShowCaption(true)
    line.SetCaptionPosition( &LineAnnotE_Top )
    line.SetTextHOffset( -60 )
    line.SetTextVOffset( 10 )
    line.RefreshAppearance()
    page.AnnotPushBack(line)
    
    line = LineAnnotCreate(doc.GetSDFDoc(), NewRect(200.0, 10.0, 400.0, 70.0))
    line.SetStartPoint( NewPoint(222.0, 25.0 ) )
    line.SetEndPoint( NewPoint(370.0,60.0) )
    line.SetStartStyle(LineAnnotE_Butt)
    line.SetEndStyle(LineAnnotE_OpenArrow)
    line.SetColor(NewColorPt(0.0, 0.0, 1.0), 3)
    line.SetContents( "Regular Caption" )
    line.SetShowCaption(true)
    line.SetCaptionPosition( &LineAnnotE_Top )
    line.RefreshAppearance()
    page.AnnotPushBack(line)
    
    line = LineAnnotCreate(doc.GetSDFDoc(), NewRect(200.0, 70.0, 400.0, 130.0))
    line.SetStartPoint( NewPoint(220.0, 111.0 ) )
    line.SetEndPoint( NewPoint(370.0,78.0) )
    line.SetStartStyle(LineAnnotE_Circle)
    line.SetEndStyle(LineAnnotE_Diamond)
    line.SetContents( "Circle to Diamond" )
    line.SetColor(NewColorPt(0.0, 0.0, 1.0), 3)
    line.SetInteriorColor(NewColorPt(0.0, 1.0, 0.0), 3)
    line.SetShowCaption(true)
    line.SetCaptionPosition( &LineAnnotE_Top )
    line.RefreshAppearance()
    page.AnnotPushBack(line)
    
    line = LineAnnotCreate(doc.GetSDFDoc(), NewRect(10.0, 100.0, 160.0, 200.0))
    line.SetStartPoint( NewPoint(15.0, 110.0 ) )
    line.SetEndPoint( NewPoint(150.0, 190.0) )
    line.SetStartStyle(LineAnnotE_Slash)
    line.SetEndStyle(LineAnnotE_ClosedArrow)
    line.SetContents( "Slash to CArrow" )
    line.SetColor(NewColorPt(1.0, 0.0, 0.0), 3)
    line.SetInteriorColor(NewColorPt(0.0, 1.0, 1.0), 3)
    line.SetShowCaption(true)
    line.SetCaptionPosition( &LineAnnotE_Top )
    line.RefreshAppearance()
    page.AnnotPushBack(line)
    
    line = LineAnnotCreate(doc.GetSDFDoc(), NewRect(270.0, 270.0, 570.0, 433.0 ))
    line.SetStartPoint( NewPoint(300.0, 400.0 ) )
    line.SetEndPoint( NewPoint(550.0, 300.0) )
    line.SetStartStyle(LineAnnotE_RClosedArrow)
    line.SetEndStyle(LineAnnotE_ROpenArrow)
    line.SetContents( "ROpen & RClosed arrows" )
    line.SetColor(NewColorPt(0.0, 0.0, 1.0), 3)
    line.SetInteriorColor(NewColorPt(0.0, 1.0, 0.0), 3)
    line.SetShowCaption(true)
    line.SetCaptionPosition( &LineAnnotE_Top )
    line.RefreshAppearance()
    page.AnnotPushBack(line)

    line = LineAnnotCreate(doc.GetSDFDoc(), NewRect(195.0, 395.0, 205.0, 505.0 ))
    line.SetStartPoint( NewPoint(200.0, 400.0 ) )
    line.SetEndPoint( NewPoint(200.0, 500.0) )
    line.RefreshAppearance()
    page.AnnotPushBack(line)
    
    line = LineAnnotCreate(doc.GetSDFDoc(), NewRect(55.0, 299.0, 150.0, 301.0 ))
    line.SetStartPoint( NewPoint(55.0, 300.0 ) )
    line.SetEndPoint( NewPoint(155.0, 300.0) )
    line.SetStartStyle(LineAnnotE_Circle)
    line.SetEndStyle(LineAnnotE_Circle)
    line.SetContents( "Caption that's longer than its line." )
    line.SetColor(NewColorPt(1.0, 0.0, 1.0), 3)
    line.SetInteriorColor(NewColorPt(0.0, 1.0, 0.0), 3)
    line.SetShowCaption(true)
    line.SetCaptionPosition( &LineAnnotE_Top )
    line.RefreshAppearance()
    page.AnnotPushBack(line)
    
    line = LineAnnotCreate(doc.GetSDFDoc(), NewRect(300.0, 200.0, 390.0, 234.0 ))
    line.SetStartPoint( NewPoint(310.0, 210.0 ) )
    line.SetEndPoint( NewPoint(380.0, 220.0) )
    line.SetColor(NewColorPt(0.0, 0.0, 0.0), 3)
    line.RefreshAppearance()
    page.AnnotPushBack(line)

    page3 := doc.PageCreate(NewRect(0.0, 0.0, 600.0, 600.0))
    ew.Begin(page3)     // begin writing to the page
    ew.End()   // save changes to the current page
    doc.PagePushBack(page3)

    circle := CircleCreate(doc.GetSDFDoc(), NewRect(300.0, 300.0, 390.0, 350.0 ))
    circle.SetColor(NewColorPt(0.0, 0.0, 0.0), 3)
    circle.RefreshAppearance()
    page3.AnnotPushBack(circle)
    
    circle = CircleCreate(doc.GetSDFDoc(), NewRect(100.0, 100.0, 200.0, 200.0 ))
    circle.SetColor(NewColorPt(0.0, 1.0, 0.0), 3)
    circle.SetInteriorColor(NewColorPt(0.0, 0.0, 1.0), 3)
	dash.Add(2.0)
	dash.Add(4.0)
    circle.SetBorderStyle( NewBorderStyle( BorderStyleE_dashed, 3.0, 0.0, 0.0, dash ) )
	dash.Clear()
    circle.SetPadding( 2.0 )
    circle.RefreshAppearance()
    page3.AnnotPushBack(circle)

    sq := SquareCreate( doc.GetSDFDoc(), NewRect(10.0, 200.0, 80.0, 300.0 ) )
    sq.SetColor(NewColorPt(0.0, 0.0, 0.0), 3)
    sq.RefreshAppearance()
    page3.AnnotPushBack( sq )

    sq = SquareCreate( doc.GetSDFDoc(), NewRect(500.0, 200.0, 580.0, 300.0 ) )
    sq.SetColor(NewColorPt(1.0, 0.0, 0.0), 3)
    sq.SetInteriorColor(NewColorPt(0.0, 1.0, 1.0), 3)
	dash.Add(4.0)
	dash.Add(2.0)
    sq.SetBorderStyle( NewBorderStyle( BorderStyleE_dashed, 6.0, 0.0, 0.0, dash ) )
	dash.Clear()
    sq.SetPadding( 4.0 )
    sq.RefreshAppearance()
    page3.AnnotPushBack( sq )
    
	polygon := PolygonCreate(doc.GetSDFDoc(), NewRect(5.0, 500.0, 125.0, 590.0))
	polygon.SetColor(NewColorPt(1.0, 0.0, 0.0), 3)
	polygon.SetInteriorColor(NewColorPt(1.0, 1.0, 0.0), 3)
	polygon.SetVertex(0, NewPoint(12.0,510.0) )
	polygon.SetVertex(1, NewPoint(100.0,510.0) )
	polygon.SetVertex(2, NewPoint(100.0,555.0) )
	polygon.SetVertex(3, NewPoint(35.0,544.0) )
	polygon.SetBorderStyle( NewBorderStyle( BorderStyleE_solid, 4.0, 0.0, 0.0 ) )
	polygon.SetPadding( 4.0 )
	polygon.RefreshAppearance()
	page3.AnnotPushBack( polygon )
	polyline := PolyLineCreate(doc.GetSDFDoc(), NewRect(400.0, 10.0, 500.0, 90.0))
	polyline.SetColor(NewColorPt(1.0, 0.0, 0.0), 3)
	polyline.SetInteriorColor(NewColorPt(0.0, 1.0, 0.0), 3)
	polyline.SetVertex(0, NewPoint(405.0,20.0) )
	polyline.SetVertex(1, NewPoint(440.0,40.0) )
	polyline.SetVertex(2, NewPoint(410.0,60.0) )
	polyline.SetVertex(3, NewPoint(470.0,80.0) )
	polyline.SetBorderStyle( NewBorderStyle( BorderStyleE_solid, 2.0, 0.0, 0.0 ) )
	polyline.SetPadding( 4.0 )
	polyline.SetStartStyle( LineAnnotE_RClosedArrow )
	polyline.SetEndStyle( LineAnnotE_ClosedArrow )
	polyline.RefreshAppearance()
	page3.AnnotPushBack( polyline )
    lk := LinkCreate( doc.GetSDFDoc(), NewRect(5.0, 5.0, 55.0, 24.0) )
    lk.RefreshAppearance()
    page3.AnnotPushBack( lk )

    page4 := doc.PageCreate(NewRect(0.0, 0.0, 600.0, 600.0))
    ew.Begin(page4)    // begin writing to the page
    ew.End()  // save changes to the current page
    doc.PagePushBack(page4)
    
    ew.Begin( page4 )
    font := FontCreate(doc.GetSDFDoc(), FontE_helvetica)
    element := eb.CreateTextBegin( font, 16.0 )
    element.SetPathFill(true)
    ew.WriteElement(element)
    element = eb.CreateTextRun( "Some random text on the page", font, 16.0 )
    element.SetTextMatrix(1.0, 0.0, 0.0, 1.0, 100.0, 500.0 )
    ew.WriteElement(element)
    ew.WriteElement( eb.CreateTextEnd() )
    ew.End()

    hl := HighlightAnnotCreate( doc.GetSDFDoc(), NewRect(100.0, 490.0, 150.0, 515.0) )
    hl.SetColor( NewColorPt(0.0,1.0,0.0), 3 )
    hl.RefreshAppearance()
    page4.AnnotPushBack( hl )

    sqly := SquigglyCreate( doc.GetSDFDoc(), NewRect(100.0, 450.0, 250.0, 600.0) )
    sqly.SetQuadPoint( 0, NewQuadPoint(NewPoint(122.0,455.0), NewPoint(240.0, 545.0), NewPoint(230.0, 595.0), NewPoint(101.0,500.0) ) )
    sqly.RefreshAppearance()
    page4.AnnotPushBack( sqly )

    cr := CaretCreate( doc.GetSDFDoc(), NewRect(100.0, 40.0, 129.0, 69.0) )
    cr.SetColor( NewColorPt(0.0,0.0,1.0), 3 )
    cr.SetSymbol( "P" )
    cr.RefreshAppearance()
    page4.AnnotPushBack( cr )
    
    page5 := doc.PageCreate(NewRect(0.0, 0.0, 600.0, 600.0))
    ew.Begin(page5)    // begin writing to the page
    ew.End()  // save changes to the current page
    doc.PagePushBack(page5)
    //fs := FileSpecCreate( doc.GetSDFDoc(), (inputPath + "butterfly.png"), false )
    page6 := doc.PageCreate(NewRect(0.0, 0.0, 600.0, 600.0))
    ew.Begin(page6)    // begin writing to the page
    ew.End()  // save changes to the current page
    doc.PagePushBack(page6)
    
        
    txt := TextCreate( doc.GetSDFDoc(), NewPoint(10.0, 20.0) )
    txt.SetIcon( "UserIcon" )
    txt.SetContents( "User defined icon, unrecognized by appearance generator" )
    txt.SetColor( NewColorPt(0.0,1.0,0.0) )
    txt.RefreshAppearance()
    page6.AnnotPushBack( txt )
    
    ink := InkCreate( doc.GetSDFDoc(), NewRect(100.0, 400.0, 200.0, 550.0 ) )
    ink.SetColor( NewColorPt(0.0,0.0,1.0) )
    ink.SetPoint( 1, 3, NewPoint( 220.0, 505.0) )
    ink.SetPoint( 1, 0, NewPoint( 100.0, 490.0) )
    ink.SetPoint( 0, 1, NewPoint( 120.0, 410.0) )
    ink.SetPoint( 0, 0, NewPoint( 100.0, 400.0) )
    ink.SetPoint( 1, 2, NewPoint( 180.0, 490.0) )
    ink.SetPoint( 1, 1, NewPoint( 140.0, 440.0) )        
    ink.SetBorderStyle( NewBorderStyle( BorderStyleE_solid, 3.0, 0.0, 0.0 ))
    ink.RefreshAppearance()
    page6.AnnotPushBack( ink )
    
    page7 := doc.PageCreate(NewRect(0.0, 0.0, 600.0, 600.0))
    ew.Begin(page7)    // begin writing to the page
    ew.End()  // save changes to the current page
    doc.PagePushBack(page7)
    
    snd := SoundCreate( doc.GetSDFDoc(), NewRect(100.0, 500.0, 120.0, 520.0 ) )
    snd.SetColor(  NewColorPt(1.0,1.0,0.0) )
    snd.SetIcon( SoundE_Speaker )
    snd.RefreshAppearance()
    page7.AnnotPushBack( snd )
    
    snd = SoundCreate( doc.GetSDFDoc(), NewRect(200.0, 500.0, 220.0, 520.0 ) )
    snd.SetColor(  NewColorPt(1.0,1.0,0.0) )
    snd.SetIcon( SoundE_Mic )
    snd.RefreshAppearance()
    page7.AnnotPushBack( snd )
    
    page8 := doc.PageCreate(NewRect(0.0, 0.0, 600.0, 600.0))
    ew.Begin(page8)    // begin writing to the page
    ew.End()  // save changes to the current page
    doc.PagePushBack(page8)
    
    ipage := 0
    for ipage<2{
        px := 5
        py := 520
        istamp := RubberStampE_Approved
        for istamp <= RubberStampE_Draft{
            st := RubberStampCreate(doc.GetSDFDoc(), NewRect(1.0, 1.0, 100.0, 100.0))
            st.SetIcon( istamp )
            st.SetContents( st.GetIconName() )
            st.SetRect( NewRect(float64(px), float64(py), float64(px+100), float64(py+25) ) )
            py -= 100
            if py < 0{
                py = 520
                px+=200
			}
            if ipage == 0{
                //page7.AnnotPushBack(st)
			}else{
                page8.AnnotPushBack( st )
                st.RefreshAppearance()
			}
            istamp = istamp + 1
		}
        ipage = ipage + 1
    }

    st := RubberStampCreate( doc.GetSDFDoc(), NewRect(400.0, 5.0, 550.0, 45.0) )
    st.SetIcon( "UserStamp" )
    st.SetContents( "User defined stamp" )
    page8.AnnotPushBack( st )
    st.RefreshAppearance()
}    

func main(){
    PDFNetInitialize(PDFTronLicense.Key)
   
    doc := NewPDFDoc(inputPath + "numbered.pdf")
    doc.InitSecurityHandler()
    
    // An example of using SDF/Cos API to add any type of annotations.
    AnnotationLowLevelAPI(doc)
    doc.Save(outputPath + "annotation_test1.pdf", uint(SDFDocE_remove_unused))
    fmt.Println("Done. Results saved in annotation_test1.pdf")
    // An example of using the high-level PDFNet API to read existing annotations,
    // to edit existing annotations, and to create new annotation from scratch.
    AnnotationHighLevelAPI(doc)
    doc.Save((outputPath + "annotation_test2.pdf"), uint(SDFDocE_linearized))
    doc.Close()
    fmt.Println("Done. Results saved in annotation_test2.pdf")
    
    doc1 := NewPDFDoc()
    CreateTestAnnots(doc1)
    outfname := outputPath + "new_annot_test_api.pdf"
    doc1.Save(outfname, uint(SDFDocE_linearized))
    fmt.Println("Saved new_annot_test_api.pdf")
    PDFNetTerminate()
}
```

{% endcode %}
{% endtab %}

{% tab title="Java" %}
{% code lineNumbers="true" %}

```java
//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
// Consult legal.txt regarding legal and license information.
//---------------------------------------------------------------------------------------

import com.pdftron.common.PDFNetException;
import com.pdftron.pdf.*;
import com.pdftron.pdf.Annot.BorderStyle;
import com.pdftron.pdf.annots.*;
import com.pdftron.sdf.SDFDoc;
import com.pdftron.sdf.Obj;

import java.text.DecimalFormat;


public class AnnotationTest {
    // Relative path to the folder containing test files.
    public static final String input_path = "../../TestFiles/";

    public static final DecimalFormat format = new DecimalFormat("0.#");

    static void AnnotationHighLevelAPI(PDFDoc doc) throws PDFNetException {
        // The following code snippet traverses all annotations in the document
        System.out.println("Traversing all annotations in the document...");

        int page_num = 1;
        for (PageIterator itr = doc.getPageIterator(); itr.hasNext(); ) {
            System.out.println("Page " + (page_num++) + ": ");

            Page page = itr.next();
            int num_annots = page.getNumAnnots();
            for (int i = 0; i < num_annots; ++i) {
                Annot annot = page.getAnnot(i);
                if (annot.isValid() == false) continue;
                System.out.println("Annot Type: " + annot.getSDFObj().get("Subtype").value().getName());

                double[] bbox = annot.getRect().get();
                System.out.println("  Position: " + format.format(bbox[0])
                        + ", " + format.format(bbox[1])
                        + ", " + format.format(bbox[2])
                        + ", " + format.format(bbox[3]));

                switch (annot.getType()) {
                    case Annot.e_Link: {
                        com.pdftron.pdf.annots.Link link = new com.pdftron.pdf.annots.Link(annot);
                        Action action = link.getAction();
                        if (action.isValid() == false) continue;
                        if (action.getType() == Action.e_GoTo) {
                            Destination dest = action.getDest();
                            if (dest.isValid() == false) {
                                System.out.println("  Destination is not valid.");
                            } else {
                                int page_link = dest.getPage().getIndex();
                                System.out.println("  Links to: page number " + page_link + " in this document");
                            }
                        } else if (action.getType() == Action.e_URI) {
                            String uri = action.getSDFObj().get("URI").value().getAsPDFText();
                            System.out.println("  Links to: " + uri);
                        }
                        // ...
                    }
                    break;
                    case Annot.e_Widget:
                        break;
                    case Annot.e_FileAttachment:
                        break;
                    // ...
                    default:
                        break;
                }
            }
        }

        // Use the high-level API to create new annotations.
        Page first_page = doc.getPage(1);

        // Create a hyperlink...
        com.pdftron.pdf.annots.Link hyperlink = com.pdftron.pdf.annots.Link.create(doc, new Rect(85, 570, 503, 524), Action.createURI(doc, "http://www.pdftron.com"));
        first_page.annotPushBack(hyperlink);

        // Create an intra-document link...
        Action goto_page_3 = Action.createGoto(Destination.createFitH(doc.getPage(3), 0));
        com.pdftron.pdf.annots.Link link = com.pdftron.pdf.annots.Link.create(doc.getSDFDoc(),
                new Rect(85, 458, 503, 502),
                goto_page_3);
        link.setColor(new ColorPt(0, 0, 1), 3);

        // Add the new annotation to the first page
        first_page.annotPushBack(link);

        // Create a stamp annotation ...
        com.pdftron.pdf.annots.RubberStamp stamp = com.pdftron.pdf.annots.RubberStamp.create(doc, new Rect(30, 30, 300, 200));
        stamp.setIcon("Draft");
        first_page.annotPushBack(stamp);

        // Create a file attachment annotation (embed the 'peppers.jpg').
        com.pdftron.pdf.annots.FileAttachment file_attach = com.pdftron.pdf.annots.FileAttachment.create(doc, new Rect(80, 280, 108, 320), (input_path + "peppers.jpg"));
        first_page.annotPushBack(file_attach);


        com.pdftron.pdf.annots.Ink ink = com.pdftron.pdf.annots.Ink.create(doc, new Rect(110, 10, 300, 200));
        Point pt3 = new Point(110, 10);
        //pt3.x = 110; pt3.y = 10;
        ink.setPoint(0, 0, pt3);
        pt3.x = 150;
        pt3.y = 50;
        ink.setPoint(0, 1, pt3);
        pt3.x = 190;
        pt3.y = 60;
        ink.setPoint(0, 2, pt3);
        pt3.x = 180;
        pt3.y = 90;
        ink.setPoint(1, 0, pt3);
        pt3.x = 190;
        pt3.y = 95;
        ink.setPoint(1, 1, pt3);
        pt3.x = 200;
        pt3.y = 100;
        ink.setPoint(1, 2, pt3);
        pt3.x = 166;
        pt3.y = 86;
        ink.setPoint(2, 0, pt3);
        pt3.x = 196;
        pt3.y = 96;
        ink.setPoint(2, 1, pt3);
        pt3.x = 221;
        pt3.y = 121;
        ink.setPoint(2, 2, pt3);
        pt3.x = 288;
        pt3.y = 188;
        ink.setPoint(2, 3, pt3);
        ink.setColor(new ColorPt(0, 1, 1), 3);
        first_page.annotPushBack(ink);

    }

    static void AnnotationLowLevelAPI(PDFDoc doc) throws PDFNetException {
        Page page = doc.getPageIterator().next();

        Obj annots = page.getAnnots();

        if (annots == null) {
            // If there are no annotations, create a new annotation
            // array for the page.
            annots = doc.createIndirectArray();
            page.getSDFObj().put("Annots", annots);
        }

        // Create a Text annotation
        Obj annot = doc.createIndirectDict();
        annot.putName("Subtype", "Text");
        annot.putBool("Open", true);
        annot.putString("Contents", "The quick brown fox ate the lazy mouse.");
        annot.putRect("Rect", 266, 116, 430, 204);

        // Insert the annotation in the page annotation array
        annots.pushBack(annot);

        // Create a Link annotation
        Obj link1 = doc.createIndirectDict();
        link1.putName("Subtype", "Link");
        Destination dest = Destination.createFit(doc.getPage(2));
        link1.put("Dest", dest.getSDFObj());
        link1.putRect("Rect", 85, 705, 503, 661);
        annots.pushBack(link1);

        // Create another Link annotation
        Obj link2 = doc.createIndirectDict();
        link2.putName("Subtype", "Link");
        Destination dest2 = Destination.createFit(doc.getPage(3));
        link2.put("Dest", dest2.getSDFObj());
        link2.putRect("Rect", 85, 638, 503, 594);
        annots.pushBack(link2);

        // Note that PDFNet APi can be used to modify existing annotations.
        // In the following example we will modify the second link annotation
        // (link2) so that it points to the 10th page. We also use a different
        // destination page fit type.

        // link2 = annots.GetAt(annots.Size()-1);
        link2.put("Dest",
                Destination.createXYZ(doc.getPage(10), 100, 792 - 70, 10).getSDFObj());

        // Create a third link annotation with a hyperlink action (all other
        // annotation types can be created in a similar way)
        Obj link3 = doc.createIndirectDict();
        link3.putName("Subtype", "Link");
        link3.putRect("Rect", 85, 570, 503, 524);

        // Create a URI action
        Obj action = link3.putDict("A");
        action.putName("S", "URI");
        action.putString("URI", "http://www.pdftron.com");

        annots.pushBack(link3);
    }


    static void CreateTestAnnots(PDFDoc doc) throws PDFNetException {
        ElementWriter ew = new ElementWriter();
        ElementBuilder eb = new ElementBuilder();
        Element element;

        Page first_page = doc.pageCreate(new Rect(0, 0, 600, 600));
        doc.pagePushBack(first_page);
        ew.begin(first_page, ElementWriter.e_overlay, false);    // begin writing to this page
        ew.end();  // save changes to the current page

        //
        // Test of a free text annotation.
        //
        {
            FreeText txtannot = FreeText.create(doc, new Rect(10, 400, 160, 570));
            txtannot.setContents("\n\nSome swift brown fox snatched a gray hare out of the air by freezing it with an angry glare." +
                    "\n\nAha!\n\nAnd there was much rejoicing!");
            txtannot.setBorderStyle(new Annot.BorderStyle(Annot.BorderStyle.e_solid, 1, 10, 20));
            txtannot.setQuaddingFormat(0);
            first_page.annotPushBack(txtannot);
            txtannot.refreshAppearance();
        }
        {
            FreeText txtannot = FreeText.create(doc, new Rect(100, 100, 350, 500));
            txtannot.setContentRect(new Rect(200, 200, 350, 500));
            txtannot.setContents("\n\nSome swift brown fox snatched a gray hare out of the air by freezing it with an angry glare." +
                    "\n\nAha!\n\nAnd there was much rejoicing!");
            txtannot.setCalloutLinePoints(new Point(200, 300), new Point(150, 290), new Point(110, 110));
            txtannot.setBorderStyle(new Annot.BorderStyle(Annot.BorderStyle.e_solid, 1, 10, 20));
            txtannot.setEndingStyle(Line.e_ClosedArrow);
            txtannot.setColor(new ColorPt(0, 1, 0));
            txtannot.setQuaddingFormat(1);
            first_page.annotPushBack(txtannot);
            txtannot.refreshAppearance();
        }
        {
            FreeText txtannot = FreeText.create(doc, new Rect(400, 10, 550, 400));
            txtannot.setContents("\n\nSome swift brown fox snatched a gray hare out of the air by freezing it with an angry glare." +
                    "\n\nAha!\n\nAnd there was much rejoicing!");
            txtannot.setBorderStyle(new Annot.BorderStyle(Annot.BorderStyle.e_solid, 1, 10, 20));
            txtannot.setColor(new ColorPt(0, 0, 1));
            txtannot.setOpacity(0.2);
            txtannot.setQuaddingFormat(2);
            first_page.annotPushBack(txtannot);
            txtannot.refreshAppearance();
        }

        Page page = doc.pageCreate(new Rect(0, 0, 600, 600));
        doc.pagePushBack(page);
        ew.begin(page, ElementWriter.e_overlay, false);    // begin writing to this page
        eb.reset();            // Reset the GState to default
        ew.end();  // save changes to the current page

        {
            //Create a Line annotation...
            Line line = Line.create(doc, new Rect(250, 250, 400, 400));
            line.setStartPoint(new Point(350, 270));
            line.setEndPoint(new Point(260, 370));
            line.setStartStyle(Line.e_Square);
            line.setEndStyle(Line.e_Circle);
            line.setColor(new ColorPt(.3, .5, 0), 3);
            line.setContents("Dashed Captioned");
            line.setShowCaption(true);
            line.setCaptionPosition(Line.e_Top);
            double[] dash = {2, 2.0};
            line.setBorderStyle(new Annot.BorderStyle(Annot.BorderStyle.e_dashed, 2, 0, 0, dash));
            line.refreshAppearance();
            page.annotPushBack(line);
        }
        {
            Line line = Line.create(doc, new Rect(347, 377, 600, 600));
            line.setStartPoint(new Point(385, 410));
            line.setEndPoint(new Point(540, 555));
            line.setStartStyle(Line.e_Circle);
            line.setEndStyle(Line.e_OpenArrow);
            line.setColor(new ColorPt(1, 0, 0), 3);
            line.setInteriorColor(new ColorPt(0, 1, 0), 3);
            line.setContents("Inline Caption");
            line.setShowCaption(true);
            line.setCaptionPosition(Line.e_Inline);
            line.setLeaderLineExtensionLength(4.);
            line.setLeaderLineLength(-12.);
            line.setLeaderLineOffset(2.);
            line.refreshAppearance();
            page.annotPushBack(line);
        }
        {
            Line line = Line.create(doc, new Rect(10, 400, 200, 600));
            line.setStartPoint(new Point(25, 426));
            line.setEndPoint(new Point(180, 555));
            line.setStartStyle(Line.e_Circle);
            line.setEndStyle(Line.e_Square);
            line.setColor(new ColorPt(0, 0, 1), 3);
            line.setInteriorColor(new ColorPt(1, 0, 0), 3);
            line.setContents("Offset Caption");
            line.setShowCaption(true);
            line.setCaptionPosition(Line.e_Top);
            line.setTextHOffset(-60);
            line.setTextVOffset(10);
            line.refreshAppearance();
            page.annotPushBack(line);
        }
        {
            Line line = Line.create(doc, new Rect(200, 10, 400, 70));
            line.setStartPoint(new Point(220, 25));
            line.setEndPoint(new Point(370, 60));
            line.setStartStyle(Line.e_Butt);
            line.setEndStyle(Line.e_OpenArrow);
            line.setColor(new ColorPt(0, 0, 1), 3);
            line.setContents("Regular Caption");
            line.setShowCaption(true);
            line.setCaptionPosition(Line.e_Top);
            line.refreshAppearance();
            page.annotPushBack(line);
        }
        {
            Line line = Line.create(doc, new Rect(200, 70, 400, 130));
            line.setStartPoint(new Point(220, 111));
            line.setEndPoint(new Point(370, 78));
            line.setStartStyle(Line.e_Circle);
            line.setEndStyle(Line.e_Diamond);
            line.setContents("Circle to Diamond");
            line.setColor(new ColorPt(0, 0, 1), 3);
            line.setInteriorColor(new ColorPt(0, 1, 0), 3);
            line.setShowCaption(true);
            line.setCaptionPosition(Line.e_Top);
            line.refreshAppearance();
            page.annotPushBack(line);
        }
        {
            Line line = Line.create(doc, new Rect(10, 100, 160, 200));
            line.setStartPoint(new Point(15, 110));
            line.setEndPoint(new Point(150, 190));
            line.setStartStyle(Line.e_Slash);
            line.setEndStyle(Line.e_ClosedArrow);
            line.setContents("Slash to CArrow");
            line.setColor(new ColorPt(1, 0, 0), 3);
            line.setInteriorColor(new ColorPt(0, 1, 1), 3);
            line.setShowCaption(true);
            line.setCaptionPosition(Line.e_Top);
            line.refreshAppearance();
            page.annotPushBack(line);
        }
        {
            Line line = Line.create(doc, new Rect(270, 270, 570, 433));
            line.setStartPoint(new Point(300, 400));
            line.setEndPoint(new Point(550, 300));
            line.setStartStyle(Line.e_RClosedArrow);
            line.setEndStyle(Line.e_ROpenArrow);
            line.setContents("ROpen & RClosed arrows");
            line.setColor(new ColorPt(0, 0, 1), 3);
            line.setInteriorColor(new ColorPt(0, 1, 0), 3);
            line.setShowCaption(true);
            line.setCaptionPosition(Line.e_Top);
            line.refreshAppearance();
            page.annotPushBack(line);
        }
        {
            Line line = Line.create(doc, new Rect(195, 395, 205, 505));
            line.setStartPoint(new Point(200, 400));
            line.setEndPoint(new Point(200, 500));
            line.refreshAppearance();
            page.annotPushBack(line);
        }
        {
            Line line = Line.create(doc, new Rect(55, 299, 150, 301));
            line.setStartPoint(new Point(55, 300));
            line.setEndPoint(new Point(155, 300));
            line.setStartStyle(Line.e_Circle);
            line.setEndStyle(Line.e_Circle);
            line.setContents("Caption that's longer than its line.");
            line.setColor(new ColorPt(1, 0, 1), 3);
            line.setInteriorColor(new ColorPt(0, 1, 0), 3);
            line.setShowCaption(true);
            line.setCaptionPosition(Line.e_Top);
            line.refreshAppearance();
            page.annotPushBack(line);
        }
        {
            Line line = Line.create(doc, new Rect(300, 200, 390, 234));
            line.setStartPoint(new Point(310, 210));
            line.setEndPoint(new Point(380, 220));
            line.setColor(new ColorPt(0, 0, 0), 3);
            line.refreshAppearance();
            page.annotPushBack(line);
        }

        Page page3 = doc.pageCreate(new Rect(0, 0, 600, 600));
        ew.begin(page3);    // begin writing to the page
        ew.end();  // save changes to the current page
        doc.pagePushBack(page3);
        {
            Circle circle = Circle.create(doc, new Rect(300, 300, 390, 350));
            circle.setColor(new ColorPt(0, 0, 0), 3);
            circle.refreshAppearance();
            page3.annotPushBack(circle);
        }
        {
            Circle circle = Circle.create(doc, new Rect(100, 100, 200, 200));
            circle.setColor(new ColorPt(0, 1, 0), 3);
            circle.setInteriorColor(new ColorPt(0, 0, 1), 3);
            double[] dash = {2, 4};
            circle.setBorderStyle(new Annot.BorderStyle(Annot.BorderStyle.e_dashed, 3, 0, 0, dash));
            circle.setPadding(2);
            circle.refreshAppearance();
            page3.annotPushBack(circle);
        }
        {
            Square sq = Square.create(doc, new Rect(10, 200, 80, 300));
            sq.setColor(new ColorPt(0, 0, 0), 3);
            sq.refreshAppearance();
            page3.annotPushBack(sq);
        }
        {
            Square sq = Square.create(doc, new Rect(500, 200, 580, 300));
            sq.setColor(new ColorPt(1, 0, 0), 3);
            sq.setInteriorColor(new ColorPt(0, 1, 1), 3);
            double[] dash = {4, 2};
            sq.setBorderStyle(new Annot.BorderStyle(Annot.BorderStyle.e_dashed, 6, 0, 0, dash));
            sq.setPadding(4);
            sq.refreshAppearance();
            page3.annotPushBack(sq);
        }
        {
            Polygon poly = Polygon.create(doc, new Rect(5, 500, 125, 590));
            poly.setColor(new ColorPt(1, 0, 0), 3);
            poly.setInteriorColor(new ColorPt(1, 1, 0), 3);
            poly.setVertex(0, new Point(12, 510));
            poly.setVertex(1, new Point(100, 510));
            poly.setVertex(2, new Point(100, 555));
            poly.setVertex(3, new Point(35, 544));
            poly.setBorderStyle(new Annot.BorderStyle(Annot.BorderStyle.e_solid, 4, 0, 0));
            poly.setPadding(4);
            poly.refreshAppearance();
            page3.annotPushBack(poly);
        }
        {
            PolyLine poly = PolyLine.create(doc, new Rect(400, 10, 500, 90));
            poly.setColor(new ColorPt(1, 0, 0), 3);
            poly.setInteriorColor(new ColorPt(0, 1, 0), 3);
            poly.setVertex(0, new Point(405, 20));
            poly.setVertex(1, new Point(440, 40));
            poly.setVertex(2, new Point(410, 60));
            poly.setVertex(3, new Point(470, 80));
            poly.setBorderStyle(new Annot.BorderStyle(Annot.BorderStyle.e_solid, 2, 0, 0));
            poly.setPadding(4);
            poly.setStartStyle(Line.e_RClosedArrow);
            poly.setEndStyle(Line.e_ClosedArrow);
            poly.refreshAppearance();
            page3.annotPushBack(poly);
        }
        {
            Link lk = Link.create(doc, new Rect(5, 5, 55, 24));
            lk.refreshAppearance();
            page3.annotPushBack(lk);
        }


        Page page4 = doc.pageCreate(new Rect(0, 0, 600, 600));
        ew.begin(page4);    // begin writing to the page
        ew.end();  // save changes to the current page
        doc.pagePushBack(page4);

        {
            ew.begin(page4);
            Font font = Font.create(doc, Font.e_helvetica);
            element = eb.createTextBegin(font, 16);
            element.setPathFill(true);
            ew.writeElement(element);
            element = eb.createTextRun("Some random text on the page", font, 16);
            element.setTextMatrix(1, 0, 0, 1, 100, 500);
            ew.writeElement(element);
            ew.writeElement(eb.createTextEnd());
            ew.end();
        }
        {
            Highlight hl = Highlight.create(doc, new Rect(100, 490, 150, 515));
            hl.setColor(new ColorPt(0, 1, 0), 3);
            hl.refreshAppearance();
            page4.annotPushBack(hl);
        }
        {
            Squiggly sq = Squiggly.create(doc, new Rect(100, 450, 250, 600));
            sq.setQuadPoint(0, new QuadPoint(new Point(122, 455), new Point(240, 545), new Point(230, 595), new Point(101, 500)));
            sq.refreshAppearance();
            page4.annotPushBack(sq);
        }
        {
            Caret cr = Caret.create(doc, new Rect(100, 40, 129, 69));
            cr.setColor(new ColorPt(0, 0, 1), 3);
            cr.setSymbol("P");
            cr.refreshAppearance();
            page4.annotPushBack(cr);
        }


        Page page5 = doc.pageCreate(new Rect(0, 0, 600, 600));
        ew.begin(page5);    // begin writing to the page
        ew.end();  // save changes to the current page
        doc.pagePushBack(page5);
        FileSpec fs = FileSpec.create(doc, input_path + "butterfly.png", false);
        Page page6 = doc.pageCreate(new Rect(0, 0, 600, 600));
        ew.begin(page6);    // begin writing to the page
        ew.end();  // save changes to the current page
        doc.pagePushBack(page6);

        {
            Text txt = Text.create(doc, new Point(10, 20));
            txt.setIcon("UserIcon");
            txt.setContents("User defined icon, unrecognized by appearance generator");
            txt.setColor(new ColorPt(0, 1, 0));
            txt.refreshAppearance();
            page6.annotPushBack(txt);
        }
        {
            Ink ink = Ink.create(doc, new Rect(100, 400, 200, 550));
            ink.setColor(new ColorPt(0, 0, 1));
            ink.setPoint(1, 3, new Point(220, 505));
            ink.setPoint(1, 0, new Point(100, 490));
            ink.setPoint(0, 1, new Point(120, 410));
            ink.setPoint(0, 0, new Point(100, 400));
            ink.setPoint(1, 2, new Point(180, 490));
            ink.setPoint(1, 1, new Point(140, 440));
            ink.setBorderStyle(new Annot.BorderStyle(Annot.BorderStyle.e_solid, 3, 0, 0));
            ink.refreshAppearance();
            page6.annotPushBack(ink);
        }


        Page page7 = doc.pageCreate(new Rect(0, 0, 600, 600));
        ew.begin(page7);    // begin writing to the page
        ew.end();  // save changes to the current page
        doc.pagePushBack(page7);

        {
            Sound snd = Sound.create(doc, new Rect(100, 500, 120, 520));
            snd.setColor(new ColorPt(1, 1, 0));
            snd.setIcon(Sound.e_Speaker);
            snd.refreshAppearance();
            page7.annotPushBack(snd);
        }
        {
            Sound snd = Sound.create(doc, new Rect(200, 500, 220, 520));
            snd.setColor(new ColorPt(1, 1, 0));
            snd.setIcon(Sound.e_Mic);
            snd.refreshAppearance();
            page7.annotPushBack(snd);
        }

        Page page8 = doc.pageCreate(new Rect(0, 0, 600, 600));
        ew.begin(page8);    // begin writing to the page
        ew.end();  // save changes to the current page
        doc.pagePushBack(page8);

        for (int ipage = 0; ipage < 2; ++ipage) {
            double px = 5, py = 520;
            for (int istamp = 0; istamp <= RubberStamp.e_Draft; ++istamp) {
                RubberStamp st = RubberStamp.create(doc, new Rect(1, 1, 100, 100));
                st.SetIcon(istamp);
                st.setContents(st.getIconName());
                st.setRect(new Rect(px, py, px + 100, py + 25));
                py -= 100;
                if (py < 0) {
                    py = 520;
                    px += 200;
                }
                if (ipage == 0)
                    //page7.AnnotPushBack( st );
                    ;
                else {
                    page8.annotPushBack(st);
                    st.refreshAppearance();
                }
            }
        }
        RubberStamp st = RubberStamp.create(doc, new Rect(400, 5, 550, 45));
        st.setIcon("UserStamp");
        st.setContents("User defined stamp");
        page8.annotPushBack(st);
        st.refreshAppearance();
    }

    public static void main(String[] args) {
        PDFNet.initialize(PDFTronLicense.Key());

        String output_path = "../../TestFiles/Output/";

        try (PDFDoc doc = new PDFDoc((input_path + "numbered.pdf"))) {
            doc.initSecurityHandler();

            // An example of using SDF/Cos API to add any type of annotations.
            AnnotationLowLevelAPI(doc);
            doc.save(output_path + "annotation_test1.pdf", SDFDoc.SaveMode.LINEARIZED, null);
            // output PDF doc
            System.out.println("Done. Results saved in annotation_test1.pdf");

            // An example of using the high-level PDFNet API to read existing annotations,
            // to edit existing annotations, and to create new annotation from scratch.
            AnnotationHighLevelAPI(doc);
            doc.save(output_path + "annotation_test2.pdf", SDFDoc.SaveMode.LINEARIZED, null);
            System.out.println("Done. Results saved in annotation_test2.pdf");
        } catch (Exception e) {
            System.out.println(e);
        }

        // an example of creating various annotations in a brand new document
        try (PDFDoc doc1 = new PDFDoc()) {
            CreateTestAnnots(doc1);
            doc1.save(output_path + "new_annot_test_api.pdf", SDFDoc.SaveMode.LINEARIZED, null);
            System.out.println("Saved new_annot_test_api.pdf");
        } catch (Exception e) {
            System.out.println(e);
        }

        PDFNet.terminate();
    }

}
```

{% endcode %}
{% endtab %}

{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
// Consult legal.txt regarding legal and license information.
//---------------------------------------------------------------------------------------


const { PDFNet } = require('@pdftron/pdfnet-node');
const PDFTronLicense = require('../LicenseKey/LicenseKey');

((exports) => {
  exports.runAnnotationTest = async() => {

    const inputPath = '../TestFiles/';

    const AnnotationHighLevelAPI = async(doc) => {
      await PDFNet.startDeallocateStack(); // start stack-based deallocation. All objects will be deallocated by end of function

      // The following code snippet traverses all annotations in the document
      console.log('Traversing all annotations in the document...');

      let pageNum = 0;
      const itr = await doc.getPageIterator();
      for (itr; (await itr.hasNext()); (await itr.next())) {
        pageNum += 1;
        console.log('Page ' + pageNum + ': ');
        const page = await itr.current();
        const numAnnots = await page.getNumAnnots();
        for (let i = 0; i < numAnnots; ++i) {
          const annot = await page.getAnnot(i);
          if (!(await annot.isValid())) {
            continue;
          }

          const annotSDF = await annot.getSDFObj();
          const subType = await annotSDF.get('Subtype');
          const subTypeVal = await subType.value();

          let outputString = 'Annot Type: ' + (await subTypeVal.getName());
          console.log(outputString);
          const bbox = await annot.getRect();
          outputString = '  Position: ' + bbox.x1 + ', ' + bbox.y1 + ', ' + bbox.x2 + ', ' + bbox.y2;
          console.log(outputString);
          const annotType = await annot.getType();
          switch (annotType) {
            case PDFNet.Annot.Type.e_Link:
              {
                const link = await PDFNet.LinkAnnot.createFromAnnot(annot);
                const action = await link.getAction();
                if (!(await action.isValid())) {
                  continue;
                }

                if ((await action.getType()) === PDFNet.Action.Type.e_GoTo) {
                  const dest = await action.getDest();
                  if (!(await dest.isValid())) {
                    console.log('  Destination is not valid');
                  } else {
                    const pageNumOut = await (await dest.getPage()).getIndex();
                    console.log('  Links to: page number ' + pageNumOut + ' in this document');
                  }
                } else if ((await action.getType()) === PDFNet.Action.Type.e_URI) {
                  const SDFObj = await action.getSDFObj();
                  const URI = await SDFObj.get('URI');
                  const URIval = await URI.value();
                  const URIText = await URIval.getAsPDFText(); // An Exception is thrown if this is not a Obj::Type::e_string.
                  console.log('  Links to: ' + URIText); // Other get methods such as getNumber do not work either, although some do, so confusing.
                  // deallocate dictionary object on C side
                  URI.destroy();
                }
              }
              break;
            case PDFNet.Annot.Type.e_Widget:
              break;
            case PDFNet.Annot.Type.e_FileAttachment:
              break;
            default:
              break;
          }

          await subType.destroy();
        }
      }
      // create a hyperlink
      const firstPage = await doc.getPage(1);
      const createURIAction = await PDFNet.Action.createURI(doc, 'http://www.pdftron.com');
      const linkRect = new PDFNet.Rect(85, 570, 503, 524);
      const hyperlink = await PDFNet.LinkAnnot.create(doc, linkRect);
      await hyperlink.setAction(createURIAction);
      await firstPage.annotPushBack(hyperlink);

      // Create an intra-document link...
      const page3 = await doc.getPage(3);
      const gotoPage3 = await PDFNet.Action.createGoto(await PDFNet.Destination.createFitH(page3, 0));
      const link = await PDFNet.LinkAnnot.create(doc, (new PDFNet.Rect(85, 458, 503, 502)));
      await link.setAction(gotoPage3);
      const greenColorPt = await PDFNet.ColorPt.init(0, 0, 1);
      await link.setColor(greenColorPt);

      // Add the new annotation to the first page
      await firstPage.annotPushBack(link);

      // Create a stamp annotation ...
      const stamp = await PDFNet.RubberStampAnnot.create(doc, (new PDFNet.Rect(30, 30, 300, 200)));
      await stamp.setIconName('Draft');
      await firstPage.annotPushBack(stamp);

      // Create a file attachment annotation (embed the 'peppers.jpg').
      const file_attach = await PDFNet.FileAttachmentAnnot.createDefault(doc, (new PDFNet.Rect(80, 280, 108, 320)), inputPath + 'peppers.jpg');
      await firstPage.annotPushBack(file_attach);

      const ink = await PDFNet.InkAnnot.create(doc, (new PDFNet.Rect(110, 10, 300, 200)));
      const pt3 = new PDFNet.Point(110, 10);
      await ink.setPoint(0, 0, pt3);
      pt3.x = 150;
      pt3.y = 50;
      await ink.setPoint(0, 1, pt3);
      pt3.x = 190;
      pt3.y = 60;
      await ink.setPoint(0, 2, pt3);
      pt3.x = 180;
      pt3.y = 90;
      await ink.setPoint(1, 0, pt3);
      pt3.x = 190;
      pt3.y = 95;
      await ink.setPoint(1, 1, pt3);
      pt3.x = 200;
      pt3.y = 100;
      await ink.setPoint(1, 2, pt3);
      pt3.x = 166;
      pt3.y = 86;
      await ink.setPoint(2, 0, pt3);
      pt3.x = 196;
      pt3.y = 96;
      await ink.setPoint(2, 1, pt3);
      pt3.x = 221;
      pt3.y = 121;
      await ink.setPoint(2, 2, pt3);
      pt3.x = 288;
      pt3.y = 188;
      await ink.setPoint(2, 3, pt3);
      const cyanColorPt = await PDFNet.ColorPt.init(0, 1, 1);
      await ink.setColor(cyanColorPt, 3);
      firstPage.annotPushBack(ink);

      await PDFNet.endDeallocateStack();
    };

    const AnnotationLowLevelAPI = async(doc) => {
      try {
        await PDFNet.startDeallocateStack(); // start stack-based deallocation. All objects will be deallocated by end of function
        const itr = await doc.getPageIterator();
        const page = await itr.current();

        let annots = await page.getAnnots();

        if (annots == null) {
          // If there are no annotations, create a new annotation
          // array for the page.
          annots = await doc.createIndirectArray();
          const sdfDoc = await page.getSDFObj();
          await sdfDoc.put('Annots', annots);
        }

        // Create a Text annotation
        const annot = await doc.createIndirectDict();
        await annot.putName('Subtype', 'Text');
        await annot.putBool('Open', true);
        await annot.putString('Contents', 'The quick brown fox ate the lazy mouse.');
        await annot.putRect('Rect', 266, 116, 430, 204);

        // Insert the annotation in the page annotation array
        await annots.pushBack(annot);

        // Create a Link annotation
        const link1 = await doc.createIndirectDict();
        await link1.putName('Subtype', 'Link');
        const dest = await PDFNet.Destination.createFit((await doc.getPage(2)));
        await link1.put('Dest', (await dest.getSDFObj()));
        await link1.putRect('Rect', 85, 705, 503, 661);
        await annots.pushBack(link1);

        // Create another Link annotation
        const link2 = await doc.createIndirectDict();
        await link2.putName('Subtype', 'Link');
        const dest2 = await PDFNet.Destination.createFit((await doc.getPage(3)));
        await link2.put('Dest', (await dest2.getSDFObj()));
        await link2.putRect('Rect', 85, 638, 503, 594);
        await annots.pushBack(link2);

        // link2 = annots.GetAt(annots.Size()-1);
        const tenthPage = await doc.getPage(10);
        // XYZ destination stands for 'left', 'top' and 'zoom' coordinates
        const XYZDestination = await PDFNet.Destination.createXYZ(tenthPage, 100, 722, 10);
        await link2.put('Dest', (await XYZDestination.getSDFObj()));

        // Create a third link annotation with a hyperlink action (all other
        // annotation types can be created in a similar way)
        const link3 = await doc.createIndirectDict();
        await link3.putName('Subtype', 'Link');
        await link3.putRect('Rect', 85, 570, 503, 524);

        // Create a URI action
        const action = await link3.putDict('A');
        await action.putName('S', 'URI');
        await action.putString('URI', 'http://www.pdftron.com');

        await annots.pushBack(link3);
        await PDFNet.endDeallocateStack();
      } catch (err) {
        console.log(err);
      }
    };

    const CreateTestAnnots = async(doc) => {
      await PDFNet.startDeallocateStack();
      const ew = await PDFNet.ElementWriter.create(); // elementWriter
      const eb = await PDFNet.ElementBuilder.create(); // elementBuilder
      let element;

      const firstPage = await doc.pageCreate(new PDFNet.Rect(0, 0, 600, 600));
      doc.pagePushBack(firstPage);
      ew.beginOnPage(firstPage, PDFNet.ElementWriter.WriteMode.e_overlay, false); // begin writing to this page
      ew.end(); // save changes to the current page

      // NOTE: The following code represents three different ways to create a text annotation.
      {
        const txtannot = await PDFNet.FreeTextAnnot.create(doc, new PDFNet.Rect(10, 400, 160, 570));
        await txtannot.setContents('\n\nSome swift brown fox snatched a gray hare out of the air by freezing it with an angry glare.\n\nAha!\n\nAnd there was much rejoicing!');
        const solidLine = await PDFNet.AnnotBorderStyle.create(PDFNet.AnnotBorderStyle.Style.e_solid, 1, 10, 20);
        await txtannot.setBorderStyle(solidLine, false);
        await txtannot.setQuaddingFormat(0);
        await firstPage.annotPushBack(txtannot);
        await txtannot.refreshAppearance();
      }

      {
        const txtannot = await PDFNet.FreeTextAnnot.create(doc, new PDFNet.Rect(100, 100, 350, 500));
        await txtannot.setContentRect(new PDFNet.Rect(200, 200, 350, 500));
        await txtannot.setContents('\n\nSome swift brown fox snatched a gray hare out of the air by freezing it with an angry glare.\n\nAha!\n\nAnd there was much rejoicing!');
        await txtannot.setCalloutLinePoints(new PDFNet.Point(200, 300), new PDFNet.Point(150, 290), new PDFNet.Point(110, 110));
        const solidLine = await PDFNet.AnnotBorderStyle.create(PDFNet.AnnotBorderStyle.Style.e_solid, 1, 10, 20);
        await txtannot.setBorderStyle(solidLine, false);
        await txtannot.setEndingStyle(PDFNet.LineAnnot.EndingStyle.e_ClosedArrow);
        const greenColorPt = await PDFNet.ColorPt.init(0, 1, 0);
        await txtannot.setColorDefault(greenColorPt); // default value of last param is 0
        await txtannot.setQuaddingFormat(1);
        await firstPage.annotPushBack(txtannot);
        await txtannot.refreshAppearance();
      }
      {
        const txtannot = await PDFNet.FreeTextAnnot.create(doc, new PDFNet.Rect(400, 10, 550, 400));
        await txtannot.setContents('\n\nSome swift brown fox snatched a gray hare out of the air by freezing it with an angry glare.\n\nAha!\n\nAnd there was much rejoicing!');
        const solidLine = await PDFNet.AnnotBorderStyle.create(PDFNet.AnnotBorderStyle.Style.e_solid, 1, 10, 20);
        await txtannot.setBorderStyle(solidLine, false);
        const redColorPt = await PDFNet.ColorPt.init(0, 0, 1);
        await txtannot.setColorDefault(redColorPt);
        await txtannot.setOpacity(0.2);
        await txtannot.setQuaddingFormat(2);
        await firstPage.annotPushBack(txtannot);
        await txtannot.refreshAppearance();
      }
      const page = await doc.pageCreate(new PDFNet.Rect(0, 0, 600, 600));
      doc.pagePushBack(page);
      await ew.beginOnPage(page, PDFNet.ElementWriter.WriteMode.e_overlay, false);
      await eb.reset();
      await ew.end(); // save changes to the current page
      {
        // Create a Line annotation...
        const line = await PDFNet.LineAnnot.create(doc, new PDFNet.Rect(250, 250, 400, 400));
        await line.setStartPoint(new PDFNet.Point(350, 270));
        await line.setEndPoint(new PDFNet.Point(260, 370));
        await line.setStartStyle(PDFNet.LineAnnot.EndingStyle.e_Square);
        await line.setEndStyle(PDFNet.LineAnnot.EndingStyle.e_Circle);
        const darkGreenColorPt = await PDFNet.ColorPt.init(0.3, 0.5, 0);
        await line.setColor(darkGreenColorPt, 3);
        await line.setContents('Dashed Captioned');
        await line.setShowCaption(true);
        await line.setCapPos(PDFNet.LineAnnot.CapPos.e_Top);
        const dash = [2.0, 2.0];
        const bStyle = await PDFNet.AnnotBorderStyle.createWithDashPattern(PDFNet.AnnotBorderStyle.Style.e_dashed, 2, 0, 0, dash);
        line.setBorderStyle(bStyle);
        line.refreshAppearance();
        page.annotPushBack(line);
      }
      {
        const line = await PDFNet.LineAnnot.create(doc, new PDFNet.Rect(347, 377, 600, 600));
        await line.setStartPoint(new PDFNet.Point(385, 410));
        await line.setEndPoint(new PDFNet.Point(540, 555));
        await line.setStartStyle(PDFNet.LineAnnot.EndingStyle.e_Circle);
        await line.setEndStyle(PDFNet.LineAnnot.EndingStyle.e_OpenArrow);
        const redColorPt = await PDFNet.ColorPt.init(1, 0, 0);
        await line.setColor(redColorPt, 3);
        const greenColorPt = await PDFNet.ColorPt.init(0, 1, 0);
        await line.setInteriorColor(greenColorPt, 3);
        await line.setContents('Inline Caption');
        await line.setShowCaption(true);
        await line.setCapPos(PDFNet.LineAnnot.CapPos.e_Inline);
        await line.setLeaderLineExtensionLength(-4.0);
        await line.setLeaderLineLength(-12);
        await line.setLeaderLineOffset(2.0);
        await line.refreshAppearance();
        page.annotPushBack(line);
      }
      {
        const line = await PDFNet.LineAnnot.create(doc, new PDFNet.Rect(10, 400, 200, 600));
        await line.setStartPoint(new PDFNet.Point(25, 426));
        await line.setEndPoint(new PDFNet.Point(180, 555));
        await line.setStartStyle(PDFNet.LineAnnot.EndingStyle.e_Circle);
        await line.setEndStyle(PDFNet.LineAnnot.EndingStyle.e_Square);
        const blueColorPt = await PDFNet.ColorPt.init(0, 0, 1);
        await line.setColor(blueColorPt, 3);
        const redColorPt = await PDFNet.ColorPt.init(1, 0, 0);
        await line.setInteriorColor(redColorPt, 3);
        await line.setContents('Offset Caption');
        await line.setShowCaption(true);
        await line.setCapPos(PDFNet.LineAnnot.CapPos.e_Top);
        await line.setTextHOffset(-60);
        await line.setTextVOffset(10);
        await line.refreshAppearance();
        page.annotPushBack(line);
      }
      {
        const line = await PDFNet.LineAnnot.create(doc, new PDFNet.Rect(200, 10, 400, 70));
        line.setStartPoint(new PDFNet.Point(220, 25));
        line.setEndPoint(new PDFNet.Point(370, 60));
        line.setStartStyle(PDFNet.LineAnnot.EndingStyle.e_Butt);
        line.setEndStyle(PDFNet.LineAnnot.EndingStyle.e_OpenArrow);
        line.setColor((await PDFNet.ColorPt.init(0, 0, 1)), 3);
        line.setContents('Regular Caption');
        line.setShowCaption(true);
        line.setCapPos(PDFNet.LineAnnot.CapPos.e_Top);
        await line.refreshAppearance();
        page.annotPushBack(line);
      }
      {
        const line = await PDFNet.LineAnnot.create(doc, new PDFNet.Rect(200, 70, 400, 130));
        line.setStartPoint(new PDFNet.Point(220, 111));
        line.setEndPoint(new PDFNet.Point(370, 78));
        line.setStartStyle(PDFNet.LineAnnot.EndingStyle.e_Circle);
        line.setEndStyle(PDFNet.LineAnnot.EndingStyle.e_Diamond);
        line.setContents('Circle to Diamond');
        line.setColor((await PDFNet.ColorPt.init(0, 0, 1)), 3);
        line.setInteriorColor((await PDFNet.ColorPt.init(0, 1, 0)), 3);
        line.setShowCaption(true);
        line.setCapPos(PDFNet.LineAnnot.CapPos.e_Top);
        line.refreshAppearance();
        page.annotPushBack(line);
      }
      {
        const line = await PDFNet.LineAnnot.create(doc, new PDFNet.Rect(10, 100, 160, 200));
        line.setStartPoint(new PDFNet.Point(15, 110));
        line.setEndPoint(new PDFNet.Point(150, 190));
        line.setStartStyle(PDFNet.LineAnnot.EndingStyle.e_Slash);
        line.setEndStyle(PDFNet.LineAnnot.EndingStyle.e_ClosedArrow);
        line.setContents('Slash to CArrow');
        line.setColor((await PDFNet.ColorPt.init(1, 0, 0)), 3);
        line.setInteriorColor((await PDFNet.ColorPt.init(0, 1, 1)), 3);
        line.setShowCaption(true);
        line.setCapPos(PDFNet.LineAnnot.CapPos.e_Top);
        line.refreshAppearance();
        page.annotPushBack(line);
      }
      {
        const line = await PDFNet.LineAnnot.create(doc, new PDFNet.Rect(270, 270, 570, 433));
        line.setStartPoint(new PDFNet.Point(300, 400));
        line.setEndPoint(new PDFNet.Point(550, 300));
        line.setStartStyle(PDFNet.LineAnnot.EndingStyle.e_RClosedArrow);
        line.setEndStyle(PDFNet.LineAnnot.EndingStyle.e_ROpenArrow);
        line.setContents('ROpen & RClosed arrows');
        line.setColor((await PDFNet.ColorPt.init(0, 0, 1)), 3);
        line.setInteriorColor((await PDFNet.ColorPt.init(0, 1, 0)), 3);
        line.setShowCaption(true);
        line.setCapPos(PDFNet.LineAnnot.CapPos.e_Top);
        line.refreshAppearance();
        page.annotPushBack(line);
      }
      {
        const line = await PDFNet.LineAnnot.create(doc, new PDFNet.Rect(195, 395, 205, 505));
        line.setStartPoint(new PDFNet.Point(200, 400));
        line.setEndPoint(new PDFNet.Point(200, 500));
        line.refreshAppearance();
        page.annotPushBack(line);
      }
      {
        const line = await PDFNet.LineAnnot.create(doc, new PDFNet.Rect(55, 299, 150, 301));
        line.setStartPoint(new PDFNet.Point(55, 300));
        line.setEndPoint(new PDFNet.Point(155, 300));
        line.setStartStyle(PDFNet.LineAnnot.EndingStyle.e_Circle);
        line.setEndStyle(PDFNet.LineAnnot.EndingStyle.e_Circle);
        line.setContents(("Caption that's longer than its line."));
        line.setColor((await PDFNet.ColorPt.init(1, 0, 1)), 3);
        line.setInteriorColor((await PDFNet.ColorPt.init(0, 1, 0)), 3);
        line.setShowCaption(true);
        line.setCapPos(PDFNet.LineAnnot.CapPos.e_Top);
        line.refreshAppearance();
        page.annotPushBack(line);
      }
      {
        const line = await PDFNet.LineAnnot.create(doc, new PDFNet.Rect(300, 200, 390, 234));
        line.setStartPoint(new PDFNet.Point(310, 210));
        line.setEndPoint(new PDFNet.Point(380, 220));
        line.setColor((await PDFNet.ColorPt.init(0, 0, 0)), 3);
        line.refreshAppearance();
        page.annotPushBack(line);
      }
      const page3 = await doc.pageCreate(new PDFNet.Rect(0, 0, 600, 600));
      ew.beginOnPage(page3); // begin writing to the page
      ew.end(); // save changes to the current page
      doc.pagePushBack(page3);
      {
        const circle = await PDFNet.CircleAnnot.create(doc, new PDFNet.Rect(300, 300, 390, 350));
        circle.setColor((await PDFNet.ColorPt.init(0, 0, 0)), 3);
        circle.refreshAppearance();
        page3.annotPushBack(circle);
      }
      {
        const circle = await PDFNet.CircleAnnot.create(doc, new PDFNet.Rect(100, 100, 200, 200));
        circle.setColor((await PDFNet.ColorPt.init(0, 1, 0)), 3);
        circle.setInteriorColor((await PDFNet.ColorPt.init(0, 0, 1)), 3);
        const dash = [2, 4];
        circle.setBorderStyle((await PDFNet.AnnotBorderStyle.createWithDashPattern(PDFNet.AnnotBorderStyle.Style.e_dashed, 3, 0, 0, dash)));
        circle.setPadding(new PDFNet.Rect(2, 2, 2, 2));
        circle.refreshAppearance();
        page3.annotPushBack(circle);
      }
      {
        const sq = await PDFNet.SquareAnnot.create(doc, new PDFNet.Rect(10, 200, 80, 300));
        sq.setColor((await PDFNet.ColorPt.init(0, 0, 0)), 3);
        sq.refreshAppearance();
        page3.annotPushBack(sq);
      }

      {
        const sq = await PDFNet.SquareAnnot.create(doc, new PDFNet.Rect(500, 200, 580, 300));
        sq.setColor((await PDFNet.ColorPt.init(1, 0, 0)), 3);
        sq.setInteriorColor((await PDFNet.ColorPt.init(0, 1, 1)), 3);
        const dash = [4, 2];
        sq.setBorderStyle((await PDFNet.AnnotBorderStyle.createWithDashPattern(PDFNet.AnnotBorderStyle.Style.e_dashed, 6, 0, 0, dash)));
        sq.setPadding(new PDFNet.Rect(4, 4, 4, 4));
        sq.refreshAppearance();
        page3.annotPushBack(sq);
      }

      {
        const poly = await PDFNet.PolygonAnnot.create(doc, new PDFNet.Rect(5, 500, 125, 590));
        poly.setColor((await PDFNet.ColorPt.init(1, 0, 0)), 3);
        poly.setInteriorColor((await PDFNet.ColorPt.init(1, 1, 0)), 3);
        poly.setVertex(0, new PDFNet.Point(12, 510));
        poly.setVertex(1, new PDFNet.Point(100, 510));
        poly.setVertex(2, new PDFNet.Point(100, 555));
        poly.setVertex(3, new PDFNet.Point(35, 544));
        const solidBorderStyle = await PDFNet.AnnotBorderStyle.create(PDFNet.AnnotBorderStyle.Style.e_solid, 4, 0, 0);
        poly.setBorderStyle(solidBorderStyle);
        poly.setPadding(new PDFNet.Rect(4, 4, 4, 4));
        poly.refreshAppearance();
        page3.annotPushBack(poly);
      }
      {
        const poly = await PDFNet.PolyLineAnnot.create(doc, new PDFNet.Rect(400, 10, 500, 90));
        poly.setColor((await PDFNet.ColorPt.init(1, 0, 0)), 3);
        poly.setInteriorColor((await PDFNet.ColorPt.init(0, 1, 0)), 3);
        poly.setVertex(0, new PDFNet.Point(405, 20));
        poly.setVertex(1, new PDFNet.Point(440, 40));
        poly.setVertex(2, new PDFNet.Point(410, 60));
        poly.setVertex(3, new PDFNet.Point(470, 80));
        poly.setBorderStyle(await PDFNet.AnnotBorderStyle.create(PDFNet.AnnotBorderStyle.Style.e_solid, 2, 0, 0));
        poly.setPadding(new PDFNet.Rect(4, 4, 4, 4));
        poly.setStartStyle(PDFNet.LineAnnot.EndingStyle.e_RClosedArrow);
        poly.setEndStyle(PDFNet.LineAnnot.EndingStyle.e_ClosedArrow);
        poly.refreshAppearance();
        page3.annotPushBack(poly);
      }
      {
        const lk = await PDFNet.LinkAnnot.create(doc, new PDFNet.Rect(5, 5, 55, 24));
        // lk.setColor(await PDFNet.ColorPt.init(0,1,0), 3 );
        lk.refreshAppearance();
        page3.annotPushBack(lk);
      }

      const page4 = await doc.pageCreate(new PDFNet.Rect(0, 0, 600, 600));
      ew.beginOnPage(page4); // begin writing to the page
      ew.end(); // save changes to the current page
      doc.pagePushBack(page4);

      {
        ew.beginOnPage(page4);
        const font = await PDFNet.Font.create(doc, PDFNet.Font.StandardType1Font.e_helvetica);
        element = await eb.createTextBeginWithFont(font, 16);
        element.setPathFill(true);
        ew.writeElement(element);
        element = await eb.createTextRun('Some random text on the page', font, 16);
        element.setTextMatrixEntries(1, 0, 0, 1, 100, 500);
        ew.writeElement(element);
        ew.writeElement((await eb.createTextEnd()));
        ew.end();
      }
      {
        const hl = await PDFNet.HighlightAnnot.create(doc, new PDFNet.Rect(100, 490, 150, 515));
        hl.setColor((await PDFNet.ColorPt.init(0, 1, 0)), 3);
        hl.refreshAppearance();
        page4.annotPushBack(hl);
      }
      {
        const sq = await PDFNet.SquigglyAnnot.create(doc, new PDFNet.Rect(100, 450, 250, 600));
        // sq.setColor(await PDFNet.ColorPt.init(1,0,0), 3 );
        sq.setQuadPoint(0, new PDFNet.QuadPoint(122, 455, 240, 545, 230, 595, 101, 500));
        sq.refreshAppearance();
        page4.annotPushBack(sq);
      }
      {
        const cr = await PDFNet.CaretAnnot.create(doc, new PDFNet.Rect(100, 40, 129, 69));
        cr.setColor((await PDFNet.ColorPt.init(0, 0, 1)), 3);
        cr.setSymbol('P');
        cr.refreshAppearance();
        page4.annotPushBack(cr);
      }


      const page5 = await doc.pageCreate(new PDFNet.Rect(0, 0, 600, 600));
      ew.beginOnPage(page5); // begin writing to the page
      ew.end(); // save changes to the current page
      doc.pagePushBack(page5);
      const fs = await PDFNet.FileSpec.create(doc, inputPath + 'butterfly.png', false);
      const page6 = await doc.pageCreate(new PDFNet.Rect(0, 0, 600, 600));
      ew.beginOnPage(page6); // begin writing to the page
      ew.end(); // save changes to the current page
      doc.pagePushBack(page6);

      {
        const txt = await PDFNet.TextAnnot.create(doc, new PDFNet.Rect(10, 20, 30, 40));
        txt.setIconName('UserIcon');
        txt.setContents('User defined icon, unrecognized by appearance generator');
        txt.setColor((await PDFNet.ColorPt.init(0, 1, 0)));
        txt.refreshAppearance();
        page6.annotPushBack(txt);
      }
      {
        const ink = await PDFNet.InkAnnot.create(doc, new PDFNet.Rect(100, 400, 200, 550));
        ink.setColor((await PDFNet.ColorPt.init(0, 0, 1)));
        ink.setPoint(1, 3, new PDFNet.Point(220, 505));
        ink.setPoint(1, 0, new PDFNet.Point(100, 490));
        ink.setPoint(0, 1, new PDFNet.Point(120, 410));
        ink.setPoint(0, 0, new PDFNet.Point(100, 400));
        ink.setPoint(1, 2, new PDFNet.Point(180, 490));
        ink.setPoint(1, 1, new PDFNet.Point(140, 440));
        ink.setBorderStyle(await PDFNet.AnnotBorderStyle.create(PDFNet.AnnotBorderStyle.Style.e_solid, 3, 0, 0));
        ink.refreshAppearance();
        page6.annotPushBack(ink);
      }


      const page7 = await doc.pageCreate(new PDFNet.Rect(0, 0, 600, 600));
      ew.beginOnPage(page7); // begin writing to the page
      ew.end(); // save changes to the current page
      doc.pagePushBack(page7);

      {
        const snd = await PDFNet.SoundAnnot.create(doc, new PDFNet.Rect(100, 500, 120, 520));
        snd.setColor((await PDFNet.ColorPt.init(1, 1, 0)));
        snd.setIcon(PDFNet.SoundAnnot.Icon.e_Speaker);
        snd.refreshAppearance();
        page7.annotPushBack(snd);
      }
      {
        const snd = await PDFNet.SoundAnnot.create(doc, new PDFNet.Rect(200, 500, 220, 520));
        snd.setColor((await PDFNet.ColorPt.init(1, 1, 0)));
        snd.setIcon(PDFNet.SoundAnnot.Icon.e_Mic);
        snd.refreshAppearance();
        page7.annotPushBack(snd);
      }

      const page8 = await doc.pageCreate(new PDFNet.Rect(0, 0, 600, 600));
      ew.beginOnPage(page8); // begin writing to the page
      ew.end(); // save changes to the current page
      doc.pagePushBack(page8);

      for (let ipage = 0; ipage < 2; ++ipage) {
        let px = 5;
        let py = 520;
        for (let istamp = PDFNet.RubberStampAnnot.Icon.e_Approved; istamp <= PDFNet.RubberStampAnnot.Icon.e_Draft; istamp++) {
          const st = await PDFNet.RubberStampAnnot.create(doc, new PDFNet.Rect(1, 1, 100, 100));
          st.setIcon(istamp);
          st.setContents((await st.getIconName()));
          st.setRect(new PDFNet.Rect(px, py, px + 100, py + 25));
          py -= 100;
          if (py < 0) {
            py = 520;
            px += 200;
          }
          if (ipage === 0) {
            // page7.annotPushBack( st );
          } else {
            page8.annotPushBack(st);
            st.refreshAppearance();
          }
        }
      }
      const st = await PDFNet.RubberStampAnnot.create(doc, new PDFNet.Rect(400, 5, 550, 45));
      st.setIconName('UserStamp');
      st.setContents('User defined stamp');
      page8.annotPushBack(st);
      st.refreshAppearance();

      await PDFNet.endDeallocateStack();
    };

    const main = async() => {
      try {
        const ret = 0;

        const doc = await PDFNet.PDFDoc.createFromFilePath(inputPath + 'numbered.pdf');
        doc.initSecurityHandler();


        await AnnotationLowLevelAPI(doc);
        await doc.save(inputPath + 'Output/annotation_test1.pdf', PDFNet.SDFDoc.SaveOptions.e_linearized);

        console.log('Done. Results saved in annotation_test1.pdf');

        // eslint-disable-next-line no-unused-vars
        const firstPage = await doc.getPage(1);

        await AnnotationHighLevelAPI(doc);
        await doc.save(inputPath + 'Output/annotation_test2.pdf', PDFNet.SDFDoc.SaveOptions.e_linearized);
        console.log('Done. Results saved in annotation_test2.pdf');

        // creating various annotations in a brand new document
        const docnew = await PDFNet.PDFDoc.create();
        await CreateTestAnnots(docnew);
        await docnew.save(inputPath + 'Output/new_annot_test_api.pdf', PDFNet.SDFDoc.SaveOptions.e_linearized);
        console.log('Saved new_annot_test_api.pdf');
        return ret;
      } catch (err) {
        console.log(err);
      }
    };
    PDFNet.runWithCleanup(main, PDFTronLicense.Key).catch(function(error){console.log('Error: ' + JSON.stringify(error));}).then(function(){return PDFNet.shutdown();});
  };
  exports.runAnnotationTest();
})(exports);
// eslint-disable-next-line spaced-comment
//# sourceURL=AnnotationTest.js
```

{% endcode %}
{% endtab %}

{% tab title="PHP" %}
{% code lineNumbers="true" %}

```php
<?php
//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2023 by Apryse Software Inc. All Rights Reserved.
// Consult LICENSE.txt regarding license information.
//---------------------------------------------------------------------------------------
if(file_exists("../../../PDFNetC/Lib/PDFNetPHP.php"))
include("../../../PDFNetC/Lib/PDFNetPHP.php");
include("../../LicenseKey/PHP/LicenseKey.php");

// Relative path to the folder containing the test files.
$input_path = getcwd()."/../../TestFiles/";
$output_path = $input_path."Output/";

function AnnotationHighLevelAPI($doc) {
	// The following code snippet traverses all annotations in the document
	echo nl2br("Traversing all annotations in the document...\n");
	$page_num = 1;

	for ( $itr = $doc->GetPageIterator(); $itr->HasNext(); $itr->Next() ) {
		echo nl2br("Page ".$page_num++.": \n");

		$page = $itr->Current();
		$num_annots = $page->GetNumAnnots(); 
		
		for ($i=0; $i<$num_annots; ++$i) 
		{
			$annot = $page->GetAnnot($i);
			if (!$annot->IsValid()) continue;
			echo nl2br("Annot Type: ".$annot->GetSDFObj()->Get("Subtype")->Value()->GetName()."\n"); 

			$bbox = $annot->GetRect();
			echo nl2br("  Position: ".$bbox->x1.", ".$bbox->y1.", ".$bbox->x2.", ".$bbox->y2."\n");

			switch ($annot->GetType()) 
			{
			case Annot::e_Link: 
				{
					$link = new Link($annot);
					$action = $link->GetAction();
					if (!$action->IsValid()) continue 2;
					if ($action->GetType() == Action::e_GoTo) 
					{
						$dest = $action->GetDest();
						if (!$dest->IsValid()) {
							echo nl2br("  Destination is not valid\n");
						}
						else {
							$page_n = $dest->GetPage()->GetIndex();
							echo nl2br("  Links to: page number ".$page_n." in this document\n");
						}
					}
					else if ($action->GetType() == Action::e_URI) 
					{						
						$uri = $action->GetSDFObj()->Get("URI")->Value()->GetAsPDFText();
						echo nl2br("  Links to: ".$uri."\n");
					}
					// ...
				}
				break;
			case Annot::e_Widget:
				break; 
			case Annot::e_FileAttachment:
				break; 
				// ...
			default:
				break; 
			}
		}
	}
	
	// Use the high-level API to create new annotations.
	$first_page = $doc->GetPage(1);

	// Create a hyperlink...
	$hyperlink = Link::CreateAnnot($doc->GetSDFDoc(), new Rect(85.0, 570.0, 503.0, 524.0), Action::CreateURI($doc->GetSDFDoc(), "http://www.pdftron.com"));
	$first_page->AnnotPushBack($hyperlink);

	// Create an intra-document link...
	$goto_page_3 = Action::CreateGoto(Destination::CreateFitH($doc->GetPage(3), 0));
	$link = Link::CreateAnnot($doc->GetSDFDoc(), new Rect(85.0, 458.0, 503.0, 502.0), $goto_page_3);
	$link->SetColor(new ColorPt(0.0, 0.0, 1.0));

	// Add the new annotation to the first page
	$first_page->AnnotPushBack($link);

	// Create a stamp annotation ...
	$stamp = RubberStamp::CreateAnnot($doc->GetSDFDoc(), new Rect(30.0, 30.0, 300.0, 200.0));
	$stamp->SetIcon("Draft");
	$first_page->AnnotPushBack($stamp);

	// Create a file attachment annotation (embed the 'peppers.jpg').
	global $input_path;
	$file_attach = FileAttachment::CreateAnnot($doc->GetSDFDoc(), new Rect(80.0, 280.0, 108.0, 320.0), ($input_path."peppers.jpg"));
	$first_page->AnnotPushBack($file_attach);

	$ink = Ink::CreateAnnot($doc->GetSDFDoc(), new Rect(110.0, 10.0, 300.0, 200.0));
	$pt3 = new Point(110.0, 10.0);
	$ink->SetPoint(0, 0, $pt3);
	$pt3->x = 150; $pt3->y = 50;
	$ink->SetPoint(0, 1, $pt3);
	$pt3->x = 190; $pt3->y = 60;
	$ink->SetPoint(0, 2, $pt3);
	$pt3->x = 180; $pt3->y = 90;
	$ink->SetPoint(1, 0, $pt3);
	$pt3->x = 190; $pt3->y = 95;
	$ink->SetPoint(1, 1, $pt3);
	$pt3->x = 200; $pt3->y = 100;
	$ink->SetPoint(1, 2, $pt3);
	$pt3->x = 166; $pt3->y = 86;
	$ink->SetPoint(2, 0, $pt3);
	$pt3->x = 196; $pt3->y = 96;
	$ink->SetPoint(2, 1, $pt3);
	$pt3->x = 221; $pt3->y = 121;
	$ink->SetPoint(2, 2, $pt3);
	$pt3->x = 288; $pt3->y = 188;
	$ink->SetPoint(2, 3, $pt3);
	$ink->SetColor(new ColorPt(0.0, 1.0, 1.0), 3);
	$first_page->AnnotPushBack($ink);


}

function AnnotationLowLevelAPI($doc) {
	$ir = $doc->GetPageIterator();
	$page = $ir->Current();
	$annots = $page->GetAnnots();

	if (!$annots)
	{
		// If there are no annotations, create a new annotation 
		// array for the page.
		$annots = $doc->CreateIndirectArray();
		$page->GetSDFObj()->Put("Annots", $annots);
	}

	// Create a Text annotation
	$annot = $doc->CreateIndirectDict();
	$annot->PutName("Subtype", "Text");
	$annot->PutBool("Open", true);
	$annot->PutString("Contents", "The quick brown fox ate the lazy mouse.");
	$annot->PutRect("Rect", 266, 116, 430, 204);

	// Insert the annotation in the page annotation array
	$annots->PushBack($annot);	

	// Create a Link annotation
	$link1 = $doc->CreateIndirectDict();
	$link1->PutName("Subtype", "Link");
	$dest = Destination::CreateFit($doc->GetPage(2));
	$link1->Put("Dest", $dest->GetSDFObj());
	$link1->PutRect("Rect", 85, 705, 503, 661);
	$annots->PushBack($link1);

	// Create another Link annotation
	$link2 = $doc->CreateIndirectDict();
	$link2->PutName("Subtype", "Link");
	$dest2 = Destination::CreateFit($doc->GetPage(3));
	$link2->Put("Dest", $dest2->GetSDFObj());
	$link2->PutRect("Rect", 85, 638, 503, 594);
	$annots->PushBack($link2);

	// Note that PDFNet API can be used to modify existing annotations. 
	// In the following example we will modify the second link annotation 
	// (link2) so that it points to the 10th page. We also use a different 
	// destination page fit type.

	// $link2 = $annots->GetAt($annots->Size()-1);
	$link2->Put("Dest", Destination::CreateXYZ($doc->GetPage(10), 100, 792-70, 10)->GetSDFObj());

	// Create a third link annotation with a hyperlink action (all other 
	// annotation types can be created in a similar way)
	$link3 = $doc->CreateIndirectDict();
	$link3->PutName("Subtype", "Link");
	$link3->PutRect("Rect", 85, 570, 503, 524);

	// Create a URI action 
	$action = $link3->PutDict("A");
	$action->PutName("S", "URI");
	$action->PutString("URI", "http://www.pdftron.com");

	$annots->PushBack($link3);
}

function CreateTestAnnots($doc) {
	$ew = new ElementWriter();
	$eb = new ElementBuilder();

	$first_page= $doc->PageCreate(new Rect(0.0, 0.0, 600.0, 600.0));
	$doc->PagePushBack($first_page);
	$ew->Begin($first_page, ElementWriter::e_overlay, false );	// begin writing to this page
	$ew->End();  // save changes to the current page
	
	//
	// Test of a free text annotation.
	//
	$txtannot = FreeText::CreateAnnot( $doc->GetSDFDoc(), new Rect(10.0, 400.0, 160.0, 570.0)  );
	$txtannot->SetContents( "\n\nSome swift brown fox snatched a gray hare out of the air by freezing it with an angry glare."
				."\n\nAha!\n\nAnd there was much rejoicing!");
	$txtannot->SetBorderStyle( new BorderStyle( BorderStyle::e_solid, 1.0, 10.0, 20.0 ), false );
	$txtannot->SetQuaddingFormat(0);
	$first_page->AnnotPushBack($txtannot);
	$txtannot->RefreshAppearance();

	$txtannot = FreeText::CreateAnnot( $doc->GetSDFDoc(), new Rect(100.0, 100.0, 350.0, 500.0)  );
	$txtannot->SetContentRect( new Rect( 200.0, 200.0, 350.0, 500.0 ) );
	$txtannot->SetContents("\n\nSome swift brown fox snatched a gray hare out of the air by freezing it with an angry glare."
			       ."\n\nAha!\n\nAnd there was much rejoicing!");
	$txtannot->SetCalloutLinePoints( new Point(200.0,300.0), new Point(150.0,290.0), new Point(110.0,110.0) );
	$txtannot->SetBorderStyle( new BorderStyle( BorderStyle::e_solid, 1.0, 10.0, 20.0 ), false );
	$txtannot->SetEndingStyle( LineAnnot::e_ClosedArrow );
	$txtannot->SetColor( new ColorPt( 0.0, 1.0, 0.0 ) );
	$txtannot->SetQuaddingFormat(1);
	$first_page->AnnotPushBack($txtannot);
	$txtannot->RefreshAppearance();

	$txtannot = FreeText::CreateAnnot( $doc->GetSDFDoc(), new Rect(400.0, 10.0, 550.0, 400.0) );
	$txtannot->SetContents("\n\nSome swift brown fox snatched a gray hare out of the air by freezing it with an angry glare."
			     ."\n\nAha!\n\nAnd there was much rejoicing!");
	$txtannot->SetBorderStyle( new BorderStyle( BorderStyle::e_solid, 1.0, 10.0, 20.0 ), false );
	$txtannot->SetColor( new ColorPt( 0.0, 0.0, 1.0 ) );
	$txtannot->SetOpacity( 0.2 );
	$txtannot->SetQuaddingFormat(2);
	$first_page->AnnotPushBack($txtannot);
	$txtannot->RefreshAppearance();

	$page = $doc->PageCreate(new Rect(0.0, 0.0, 600.0, 600.0));
	$doc->PagePushBack($page);
	$ew->Begin($page, ElementWriter::e_overlay, false );	// begin writing to this page
	$eb->Reset();			// Reset the GState to default
	$ew->End();  // save changes to the current page

	//Create a Line annotation...
	$line = LineAnnot::CreateAnnot($doc->GetSDFDoc(), new Rect(250.0, 250.0, 400.0, 400.0));
	$line->SetStartPoint( new Point(350.0, 270.0) );
	$line->SetEndPoint( new Point(260.0,370.0) );
	$line->SetStartStyle(LineAnnot::e_Square);
	$line->SetEndStyle(LineAnnot::e_Circle);
	$line->SetColor(new ColorPt(0.3, 0.5, 0.0), 3);
	$line->SetContents( "Dashed Captioned" );
	$line->SetShowCaption(true);
	$line->SetCaptionPosition( LineAnnot::e_Top );
	$line->SetBorderStyle(new BorderStyle(BorderStyle::e_dashed, 2.0, 0.0, 0.0, array(2.0, 2.0)));
	$line->RefreshAppearance();
	$page->AnnotPushBack($line);

	$line = LineAnnot::CreateAnnot($doc->GetSDFDoc(), new Rect(347.0, 377.0, 600.0, 600.0));
	$line->SetStartPoint( new Point(385.0, 410.0) );
	$line->SetEndPoint( new Point(540.0,555.0) );
	$line->SetStartStyle(LineAnnot::e_Circle);
	$line->SetEndStyle(LineAnnot::e_OpenArrow);
	$line->SetColor(new ColorPt(1.0, 0.0, 0.0), 3);
	$line->SetInteriorColor(new ColorPt(0.0, 1.0, 0.0), 3);
	$line->SetContents("Inline Caption");
	$line->SetShowCaption(true);
	$line->SetCaptionPosition( LineAnnot::e_Inline );
	$line->SetLeaderLineExtensionLength( 4.0 );
	$line->SetLeaderLineLength( -12.0 );
	$line->SetLeaderLineOffset( 2.0 );
	$line->RefreshAppearance();
	$page->AnnotPushBack($line);

	$line = LineAnnot::CreateAnnot($doc->GetSDFDoc(), new Rect(10.0, 400.0, 200.0, 600.0));
	$line->SetStartPoint( new Point(25.0, 426.0) );
	$line->SetEndPoint( new Point(180.0,555.0) );
	$line->SetStartStyle(LineAnnot::e_Circle);
	$line->SetEndStyle(LineAnnot::e_Square);
	$line->SetColor(new ColorPt(0.0, 0.0, 1.0), 3);
	$line->SetInteriorColor(new ColorPt(1.0, 0.0, 0.0), 3);
	$line->SetContents("Offset Caption");
	$line->SetShowCaption(true);
	$line->SetCaptionPosition( LineAnnot::e_Top );
	$line->SetTextHOffset( -60 );
	$line->SetTextVOffset( 10 );
	$line->RefreshAppearance();
	$page->AnnotPushBack($line);

	$line = LineAnnot::CreateAnnot($doc->GetSDFDoc(), new Rect(200.0, 10.0, 400.0, 70.0));
	$line->SetStartPoint( new Point(220.0, 25.0) );
	$line->SetEndPoint( new Point(370.0,60.0) );
	$line->SetStartStyle(LineAnnot::e_Butt);
	$line->SetEndStyle(LineAnnot::e_OpenArrow);
	$line->SetColor(new ColorPt(0.0, 0.0, 1.0), 3);
	$line->SetContents("Regular Caption");
	$line->SetShowCaption(true);
	$line->SetCaptionPosition( LineAnnot::e_Top );
	$line->RefreshAppearance();
	$page->AnnotPushBack($line);

	$line = LineAnnot::CreateAnnot($doc->GetSDFDoc(), new Rect(200.0, 70.0, 400.0, 130.0));
	$line->SetStartPoint( new Point(220.0, 111.0) );
	$line->SetEndPoint( new Point(370.0,78.0) );
	$line->SetStartStyle(LineAnnot::e_Circle);
	$line->SetEndStyle(LineAnnot::e_Diamond);
	$line->SetContents("Circle to Diamond");
	$line->SetColor(new ColorPt(0.0, 0.0, 1.0), 3);
	$line->SetInteriorColor(new ColorPt(0.0, 1.0, 0.0), 3);
	$line->SetShowCaption(true);
	$line->SetCaptionPosition( LineAnnot::e_Top );
	$line->RefreshAppearance();
	$page->AnnotPushBack($line);

	$line = LineAnnot::CreateAnnot($doc->GetSDFDoc(), new Rect(10.0, 100.0, 160.0, 200.0));
	$line->SetStartPoint( new Point(15.0, 110.0) );
	$line->SetEndPoint( new Point(150.0, 190.0) );
	$line->SetStartStyle(LineAnnot::e_Slash);
	$line->SetEndStyle(LineAnnot::e_ClosedArrow);
	$line->SetContents("Slash to CArrow");
	$line->SetColor(new ColorPt(1.0, 0.0, 0.0), 3);
	$line->SetInteriorColor(new ColorPt(0.0, 1.0, 1.0), 3);
	$line->SetShowCaption(true);
	$line->SetCaptionPosition( LineAnnot::e_Top );
	$line->RefreshAppearance();
	$page->AnnotPushBack($line);	
	
	$line = LineAnnot::CreateAnnot($doc->GetSDFDoc(), new Rect( 270.0, 270.0, 570.0, 433.0 ));
	$line->SetStartPoint( new Point(300.0, 400.0 ) );
	$line->SetEndPoint( new Point(550.0, 300.0) );
	$line->SetStartStyle(LineAnnot::e_RClosedArrow);
	$line->SetEndStyle(LineAnnot::e_ROpenArrow);
	$line->SetContents("ROpen & RClosed arrows");
	$line->SetColor(new ColorPt(0.0, 0.0, 1.0), 3);
	$line->SetInteriorColor(new ColorPt(0.0, 1.0, 0.0), 3);
	$line->SetShowCaption(true);
	$line->SetCaptionPosition( LineAnnot::e_Top );
	$line->RefreshAppearance();
	$page->AnnotPushBack($line);

	$line = LineAnnot::CreateAnnot($doc->GetSDFDoc(), new Rect( 195.0, 395.0, 205.0, 505.0 ));
	$line->SetStartPoint( new Point(200.0, 400.0 ) );
	$line->SetEndPoint( new Point(200.0, 500.0) );
	$line->RefreshAppearance();
	$page->AnnotPushBack($line);

	$line = LineAnnot::CreateAnnot($doc->GetSDFDoc(), new Rect( 55.0, 299.0, 150.0, 301.0 ));
	$line->SetStartPoint( new Point(55.0, 300.0 ) );
	$line->SetEndPoint( new Point(155.0, 300.0) );
	$line->SetStartStyle(LineAnnot::e_Circle);
	$line->SetEndStyle(LineAnnot::e_Circle);
	$line->SetContents("Caption that's longer than its line.");
	$line->SetColor(new ColorPt(1.0, 0.0, 1.0), 3);
	$line->SetInteriorColor(new ColorPt(0.0, 1.0, 0.0), 3);
	$line->SetShowCaption(true);
	$line->SetCaptionPosition( LineAnnot::e_Top );
	$line->RefreshAppearance();
	$page->AnnotPushBack($line);

	$line = LineAnnot::CreateAnnot($doc->GetSDFDoc(), new Rect( 300.0, 200.0, 390.0, 234.0 ));
	$line->SetStartPoint( new Point(310.0, 210.0 ) );
	$line->SetEndPoint( new Point(380.0, 220.0) );
	$line->SetColor(new ColorPt(0.0, 0.0, 0.0), 3);
	$line->RefreshAppearance();
	$page->AnnotPushBack($line);

	$page3 = $doc->PageCreate(new Rect(0.0, 0.0, 600.0, 600.0));
	$ew->Begin($page3);	// begin writing to the page
	$ew->End();  // save changes to the current page
	$doc->PagePushBack($page3);

	$circle = Circle::CreateAnnot($doc->GetSDFDoc(), new Rect( 300.0, 300.0, 390.0, 350.0 ));
	$circle->SetColor(new ColorPt(0.0, 0.0, 0.0), 3);
	$circle->RefreshAppearance();
	$page3->AnnotPushBack($circle);

	$circle = Circle::CreateAnnot($doc->GetSDFDoc(), new Rect( 100.0, 100.0, 200.0, 200.0 ));
	$circle->SetColor(new ColorPt(0.0, 1.0, 0.0), 3);
	$circle->SetInteriorColor(new ColorPt(0.0, 0.0, 1.0), 3);
	$circle->SetBorderStyle( new BorderStyle( BorderStyle::e_dashed, 3.0, 0.0, 0.0, array(2.0, 4.0)) );
	$circle->SetPadding( 2.0 );
	$circle->RefreshAppearance();
	$page3->AnnotPushBack($circle);

	$sq = Square::CreateAnnot( $doc->GetSDFDoc(), new Rect(10.0,200.0, 80.0, 300.0 ) );
    	$sq->SetColor(new ColorPt(0.0, 0.0, 0.0), 3);
    	$sq->RefreshAppearance();
    	$page3->AnnotPushBack( $sq );
	
	$sq = Square::CreateAnnot( $doc->GetSDFDoc(), new Rect(500.0,200.0, 580.0, 300.0 ) );
	$sq->SetColor(new ColorPt(1.0, 0.0, 0.0), 3);
	$sq->SetInteriorColor(new ColorPt(0.0, 1.0, 1.0), 3);
	$sq->SetBorderStyle( new BorderStyle( BorderStyle::e_dashed, 6.0, 0.0, 0.0, array(4.0, 2.0) ) );
	$sq->SetPadding( 4.0 );
	$sq->RefreshAppearance();
	$page3->AnnotPushBack( $sq );
    
	$poly = Polygon::CreateAnnot($doc->GetSDFDoc(), new Rect(5.0, 500.0, 125.0, 590.0));
	$poly->SetColor(new ColorPt(1.0, 0.0, 0.0), 3);
	$poly->SetInteriorColor(new ColorPt(1.0, 1.0, 0.0), 3);
	$poly->SetVertex(0, new Point(12.0,510.0) );
	$poly->SetVertex(1, new Point(100.0,510.0) );
	$poly->SetVertex(2, new Point(100.0,555.0) );
	$poly->SetVertex(3, new Point(35.0,544.0) );
	$poly->SetBorderStyle( new BorderStyle( BorderStyle::e_solid, 4.0, 0.0, 0.0 ) );
	$poly->SetPadding( 4.0 );
	$poly->RefreshAppearance();
	$page3->AnnotPushBack( $poly );

	$poly = PolyLine::CreateAnnot($doc->GetSDFDoc(), new Rect(400.0, 10.0, 500.0, 90.0));
	$poly->SetColor(new ColorPt(1.0, 0.0, 0.0), 3);
	$poly->SetInteriorColor(new ColorPt(0.0, 1.0, 0.0), 3);
	$poly->SetVertex(0, new Point(405.0,20.0) );
	$poly->SetVertex(1, new Point(440.0,40.0) );
	$poly->SetVertex(2, new Point(410.0,60.0) );
	$poly->SetVertex(3, new Point(470.0,80.0) );
	$poly->SetBorderStyle( new BorderStyle( BorderStyle::e_solid, 2.0, 0.0, 0.0 ) );
	$poly->SetPadding( 4.0 );
	$poly->SetStartStyle( LineAnnot::e_RClosedArrow );
	$poly->SetEndStyle( LineAnnot::e_ClosedArrow );
	$poly->RefreshAppearance();
	$page3->AnnotPushBack( $poly );

	$lk = Link::CreateAnnot( $doc->GetSDFDoc(), new Rect(5.0,5.0,55.0,24.0) );
	//$lk->SetColor( new ColorPt(0.0,1.0,0.0), 3.0 );
	$lk->RefreshAppearance();
	$page3->AnnotPushBack( $lk );

	$page4 = $doc->PageCreate(new Rect(0.0, 0.0, 600.0, 600.0));
	$ew->Begin($page4);	// begin writing to the page
	$ew->End();  // save changes to the current page
	$doc->PagePushBack($page4);

	$ew->Begin( $page4 );
	$font = Font::Create($doc->GetSDFDoc(), Font::e_helvetica);
	$element = $eb->CreateTextBegin( $font, 16.0 );
	$element->SetPathFill(true);
	$ew->WriteElement($element);
	$element = $eb->CreateTextRun( "Some random text on the page", $font, 16.0 );
	$element->SetTextMatrix(1.0, 0.0, 0.0, 1.0, 100.0, 500.0 );
	$ew->WriteElement($element);
	$ew->WriteElement( $eb->CreateTextEnd() );
	$ew->End();

	$hl = HighlightAnnot::CreateAnnot( $doc->GetSDFDoc(), new Rect(100.0,490.0,150.0,515.0) );
	$hl->SetColor( new ColorPt(0.0,1.0,0.0), 3 );
	$hl->RefreshAppearance();
	$page4->AnnotPushBack( $hl );

	$sq = Squiggly::CreateAnnot( $doc->GetSDFDoc(), new Rect(100.0,450.0,250.0,600.0) );
	$sq->SetQuadPoint( 0, new QuadPoint( new Point( 122.0,455.0), new Point(240.0, 545.0), new Point(230.0, 595.0), new Point(101.0,500.0 ) ) );
	$sq->RefreshAppearance();
	$page4->AnnotPushBack( $sq );

	$cr = Caret::CreateAnnot( $doc->GetSDFDoc(), new Rect(100.0,40.0,129.0,69.0) );
	$cr->SetColor( new ColorPt(0.0,0.0,1.0), 3 );
	$cr->SetSymbol( "P" );
	$cr->RefreshAppearance();
	$page4->AnnotPushBack( $cr );

	$page5 = $doc->PageCreate(new Rect(0.0, 0.0, 600.0, 600.0));
	$ew->Begin($page5);	// begin writing to the page
	$ew->End();  // save changes to the current page
	$doc->PagePushBack($page5);
	global $input_path;
	$fs = FileSpec::Create( $doc->GetSDFDoc(), $input_path."butterfly.png", false );
	$page6 = $doc->PageCreate(new Rect(0.0, 0.0, 600.0, 600.0));
	$ew->Begin($page6);	// begin writing to the page
	$ew->End();  // save changes to the current page
	$doc->PagePushBack($page6);


	$txt = Text::CreateAnnot( $doc->GetSDFDoc(), new Point(10.0, 20.0) );
	$txt->SetIcon( "UserIcon" );
	$txt->SetContents( "User defined icon, unrecognized by appearance generator" );
	$txt->SetColor( new ColorPt(0.0,1.0,0.0) );
	$txt->RefreshAppearance();
	$page6->AnnotPushBack( $txt );

	$ink = Ink::CreateAnnot( $doc->GetSDFDoc(), new Rect( 100.0, 400.0, 200.0, 550.0 ) );
	$ink->SetColor( new ColorPt(0.0,0.0,1.0) );
	$ink->SetPoint( 1, 3, new Point( 220.0, 505.0) );
	$ink->SetPoint( 1, 0, new Point( 100.0, 490.0) );
	$ink->SetPoint( 0, 1, new Point( 120.0, 410.0) );
	$ink->SetPoint( 0, 0, new Point( 100.0, 400.0) );
	$ink->SetPoint( 1, 2, new Point( 180.0, 490.0) );
	$ink->SetPoint( 1, 1, new Point( 140.0, 440.0) );		
	$ink->SetBorderStyle( new BorderStyle( BorderStyle::e_solid, 3.0, 0.0, 0.0  ) );
	$ink->RefreshAppearance();
	$page6->AnnotPushBack( $ink );

	$page7 = $doc->PageCreate(new Rect(0.0, 0.0, 600.0, 600.0));
	$ew->Begin($page7);	// begin writing to the page
	$ew->End();  // save changes to the current page
	$doc->PagePushBack($page7);

	$snd = Sound::CreateAnnot( $doc->GetSDFDoc(), new Rect( 100.0, 500.0, 120.0, 520.0 ) );
	$snd->SetColor( new ColorPt(1.0,1.0,0.0) );
	$snd->SetIcon( Sound::e_Speaker );
	$snd->RefreshAppearance();
	$page7->AnnotPushBack( $snd );

	$snd = Sound::CreateAnnot( $doc->GetSDFDoc(), new Rect( 200.0, 500.0, 220.0, 520.0 ) );
	$snd->SetColor( new ColorPt(1.0,1.0,0.0) );
	$snd->SetIcon( Sound::e_Mic );
	$snd->RefreshAppearance();
	$page7->AnnotPushBack( $snd );

	$page8 = $doc->PageCreate(new Rect(0.0, 0.0, 600.0, 600.0));
	$ew->Begin($page8);	// begin writing to the page
	$ew->End();  // save changes to the current page
	$doc->PagePushBack($page8);

	for( $ipage =0; $ipage < 2; ++$ipage ) {
		$px = 5;
		$py = 520;
		for( $istamp = RubberStamp::e_Approved; $istamp <= RubberStamp::e_Draft; $istamp = $istamp + 1 ) {
				$st = RubberStamp::CreateAnnot( $doc->GetSDFDoc(), new Rect(1.0,1.0,100.0,100.0) );
				$st->SetIcon( $istamp );
				$st->SetContents( $st->GetIconName() );
				$st->SetRect( new Rect((double)$px, (double)$py, (double)$px+100.0, (double)$py+25.0 ) );
				$py -= 100;
				if( $py < 0 ) {
					$py = 520;
					$px += 200;
				}
				if( $ipage == 0 ) {
					//$page7->AnnotPushBack( $st );
				}
				else {
					$page8->AnnotPushBack( $st );
					$st->RefreshAppearance();
				}
		}
	}

	$st = RubberStamp::CreateAnnot( $doc->GetSDFDoc(), new Rect(400.0,5.0,550.0,45.0) );
	$st->SetIcon( "UserStamp" );
	$st->SetContents( "User defined stamp" );
	$page8->AnnotPushBack( $st );
	$st->RefreshAppearance();
}
	
	PDFNet::Initialize($LicenseKey);
	PDFNet::GetSystemFontList();    // Wait for fonts to be loaded if they haven't already. This is done because PHP can run into errors when shutting down if font loading is still in progress.

	$doc = new PDFDoc($input_path."numbered.pdf");
	$doc->InitSecurityHandler();
	
	// An example of using SDF/Cos API to add any type of annotations.
	AnnotationLowLevelAPI($doc);
	$doc->Save($output_path."annotation_test1.pdf", SDFDoc::e_remove_unused);
	echo nl2br("Done. Results saved in annotation_test1.pdf\n");

	// An example of using the high-level PDFNet API to read existing annotations,
	// to edit existing annotations, and to create new annotation from scratch.
	AnnotationHighLevelAPI($doc);
	$doc->Save($output_path."annotation_test2.pdf", SDFDoc::e_linearized);
	echo nl2br("Done. Results saved in annotation_test2.pdf\n");

	// an example of creating various annotations in a brand new document
	$doc1 = new PDFDoc();
	CreateTestAnnots( $doc1 );
	$outfname = $output_path."new_annot_test_api.pdf";
	$doc1->Save($outfname, SDFDoc::e_linearized);
	echo nl2br("Saved new_annot_test_api.pdf");
	
    $doc->Close();
	PDFNet::Terminate();
?>
```

{% endcode %}
{% endtab %}

{% tab title="Python" %}
{% code lineNumbers="true" %}

```python
#---------------------------------------------------------------------------------------
# Copyright (c) 2001-2023 by Apryse Software Inc. All Rights Reserved.
# Consult LICENSE.txt regarding license information.
#---------------------------------------------------------------------------------------

import site
site.addsitedir("../../../PDFNetC/Lib")
import sys
from PDFNetPython import *

sys.path.append("../../LicenseKey/PYTHON")
from LicenseKey import *

def AnnotationHighLevelAPI(doc):
    # The following code snippet traverses all annotations in the document
    print("Traversing all annotations in the document...")
    page_num = 1
    itr = doc.GetPageIterator()
    
    while itr.HasNext():
        print("Page " + str(page_num) + ": ")
        page_num = page_num + 1
        page = itr.Current()
        num_annots = page.GetNumAnnots()
        i = 0
        while i < num_annots:
            annot = page.GetAnnot(i)
            if not annot.IsValid():
                continue
            print("Annot Type: " + annot.GetSDFObj().Get("Subtype").Value().GetName())
            
            bbox = annot.GetRect()
            formatter = '{0:g}'
            print("  Position: " + formatter.format(bbox.x1) + 
                  ", " + formatter.format(bbox.y1) +
                  ", " + formatter.format(bbox.x2) + 
                  ", " + formatter.format(bbox.y2))
            
            type = annot.GetType()
            
            if type == Annot.e_Link:
                link = Link(annot)
                action = link.GetAction()
                if not action.IsValid():
                    continue
                if action.GetType() == Action.e_GoTo:
                    dest = action.GetDest()
                    if not dest.IsValid():
                        print("  Destination is not valid.")
                    else:
                        page_n = dest.GetPage().GetIndex()
                        print("  Links to: page number " + str(page_n) + " in this document")
                elif action.GetType() == Action.e_URI:
                    uri = action.GetSDFObj().Get("URI").Value().GetAsPDFText()
                    print("  Links to: " + str(uri))
            elif type == Annot.e_Widget:
                pass
            elif type == Annot.e_FileAttachment:
                pass
            i = i + 1
        itr.Next()

    # Use the high-level API to create new annotations.        
    first_page = doc.GetPage(1)
    
    # Create a hyperlink...
    hyperlink = Link.Create(doc.GetSDFDoc(), Rect(85, 570, 503, 524), Action.CreateURI(doc.GetSDFDoc(), "http://www.pdftron.com"))
    first_page.AnnotPushBack(hyperlink)
    
    # Create an intra-document link...
    goto_page_3 = Action.CreateGoto(Destination.CreateFitH(doc.GetPage(3), 0))
    link = Link.Create(doc.GetSDFDoc(), Rect(85, 458, 503, 502), goto_page_3)
    link.SetColor(ColorPt(0, 0, 1))
    
    # Add the new annotation to the first page
    first_page.AnnotPushBack(link) 
    
    # Create a stamp annotation ...
    stamp = RubberStamp.Create(doc.GetSDFDoc(), Rect(30, 30, 300, 200))
    stamp.SetIcon("Draft")
    first_page.AnnotPushBack(stamp)
    
    # Create a file attachment annotation (embed the 'peppers.jpg').
    file_attach = FileAttachment.Create(doc.GetSDFDoc(), Rect(80, 280, 108, 320), (input_path + "peppers.jpg"))
    first_page.AnnotPushBack(file_attach)


    ink = Ink.Create(doc.GetSDFDoc(), Rect(110, 10, 300, 200))
    pt3 = Point(110, 10)
    pt3.x = 110 
    pt3.y = 10
    ink.SetPoint(0, 0, pt3)
    pt3.x = 150 
    pt3.y = 50
    ink.SetPoint(0, 1, pt3)
    pt3.x = 190 
    pt3.y = 60
    ink.SetPoint(0, 2, pt3)
    pt3.x = 180 
    pt3.y = 90
    ink.SetPoint(1, 0, pt3)
    pt3.x = 190 
    pt3.y = 95
    ink.SetPoint(1, 1, pt3)
    pt3.x = 200 
    pt3.y = 100
    ink.SetPoint(1, 2, pt3)
    pt3.x = 166 
    pt3.y = 86
    ink.SetPoint(2, 0, pt3)
    pt3.x = 196 
    pt3.y = 96
    ink.SetPoint(2, 1, pt3)
    pt3.x = 221 
    pt3.y = 121
    ink.SetPoint(2, 2, pt3)
    pt3.x = 288 
    pt3.y = 188
    ink.SetPoint(2, 3, pt3)
    ink.SetColor(ColorPt(0, 1, 1), 3)
    first_page.AnnotPushBack(ink)

def AnnotationLowLevelAPI(doc):
    itr = doc.GetPageIterator()
    page = itr.Current()
    annots = page.GetAnnots()
    
    if annots == None:
        # If there are no annotations, create a new annotation 
        # array for the page.
        annots = doc.CreateIndirectArray()
        page.GetSDFObj().Put("Annots", annots)

    # Create a Text annotation
    annot = doc.CreateIndirectDict()
    annot.PutName("Subtype", "Text")
    annot.PutBool("Open", True)
    annot.PutString("Contents", "The quick brown fox ate the lazy mouse.")
    annot.PutRect("Rect", 266, 116, 430, 204)

    # Insert the annotation in the page annotation array
    annots.PushBack(annot)   
    
    # Create a Link annotation
    link1 = doc.CreateIndirectDict()
    link1.PutName("Subtype", "Link")
    dest = Destination.CreateFit(doc.GetPage(2))
    link1.Put("Dest", dest.GetSDFObj())
    link1.PutRect("Rect", 85, 705, 503, 661)
    annots.PushBack(link1)

    # Create another Link annotation
    link2 = doc.CreateIndirectDict()
    link2.PutName("Subtype", "Link")
    dest2 = Destination.CreateFit((doc.GetPage(3)))
    link2.Put("Dest", dest2.GetSDFObj())
    link2.PutRect("Rect", 85, 638, 503, 594)
    annots.PushBack(link2)
    
    # Note that PDFNet APi can be used to modify existing annotations. 
    # In the following example we will modify the second link annotation 
    # (link2) so that it points to the 10th page. We also use a different 
    # destination page fit type.
    
    # link2 = annots.GetAt(annots.Size()-1)
    link2.Put("Dest", Destination.CreateXYZ(doc.GetPage(10), 100, 792-70, 10).GetSDFObj())
    
    # Create a third link annotation with a hyperlink action (all other 
    # annotation types can be created in a similar way)
    link3 = doc.CreateIndirectDict()
    link3.PutName("Subtype", "Link")
    link3.PutRect("Rect", 85, 570, 503, 524)
    
    # Create a URI action 
    action = link3.PutDict("A")
    action.PutName("S", "URI")
    action.PutString("URI", "http://www.pdftron.com")
    
    annots.PushBack(link3)
    
def CreateTestAnnots(doc):
    ew = ElementWriter()
    eb = ElementBuilder()
    
    first_page = doc.PageCreate(Rect(0, 0, 600, 600))
    doc.PagePushBack(first_page)
    ew.Begin(first_page, ElementWriter.e_overlay, False )   # begin writing to this page
    ew.End()    # save changes to the current page
    
    # Test of a free text annotation.
    txtannot = FreeText.Create( doc.GetSDFDoc(), Rect(10, 400, 160, 570)  )
    txtannot.SetContents( "\n\nSome swift brown fox snatched a gray hare out " +
                          "of the air by freezing it with an angry glare." +
                          "\n\nAha!\n\nAnd there was much rejoicing!"    )
    txtannot.SetBorderStyle( BorderStyle( BorderStyle.e_solid, 1, 10, 20 ), False )
    txtannot.SetQuaddingFormat(0)
    first_page.AnnotPushBack(txtannot)
    txtannot.RefreshAppearance()
    
    txtannot = FreeText.Create( doc.GetSDFDoc(), Rect(100, 100, 350, 500)  )
    txtannot.SetContentRect( Rect( 200, 200, 350, 500 ) )
    txtannot.SetContents( "\n\nSome swift brown fox snatched a gray hare out of the air "
                            "by freezing it with an angry glare."
                            "\n\nAha!\n\nAnd there was much rejoicing!"    )
    txtannot.SetCalloutLinePoints( Point(200,300), Point(150,290), Point(110,110) )
    txtannot.SetBorderStyle( BorderStyle( BorderStyle.e_solid, 1, 10, 20 ), False )
    txtannot.SetEndingStyle( LineAnnot.e_ClosedArrow )
    txtannot.SetColor( ColorPt( 0, 1, 0 ) )
    txtannot.SetQuaddingFormat(1)
    first_page.AnnotPushBack(txtannot)
    txtannot.RefreshAppearance()
    
    txtannot = FreeText.Create( doc.GetSDFDoc(), Rect(400, 10, 550, 400)  )    
    txtannot.SetContents( "\n\nSome swift brown fox snatched a gray hare out of the air "
                          "by freezing it with an angry glare."
                          "\n\nAha!\n\nAnd there was much rejoicing!"    )
    txtannot.SetBorderStyle( BorderStyle( BorderStyle.e_solid, 1, 10, 20 ), False )
    txtannot.SetColor( ColorPt( 0, 0, 1 ) )
    txtannot.SetOpacity( 0.2 )
    txtannot.SetQuaddingFormat(2)
    first_page.AnnotPushBack(txtannot)
    txtannot.RefreshAppearance()
    
    page= doc.PageCreate(Rect(0, 0, 600, 600))
    doc.PagePushBack(page)
    ew.Begin(page, ElementWriter.e_overlay, False )    # begin writing to this page
    eb.Reset()  # Reset the GState to default
    ew.End()    # save changes to the current page
    
    # Create a Line annotation...
    line=LineAnnot.Create(doc.GetSDFDoc(), Rect(250, 250, 400, 400))
    line.SetStartPoint( Point(350, 270 ) )
    line.SetEndPoint( Point(260,370) )
    line.SetStartStyle(LineAnnot.e_Square)
    line.SetEndStyle(LineAnnot.e_Circle)
    line.SetColor(ColorPt(.3, .5, 0), 3)
    line.SetContents( "Dashed Captioned" )
    line.SetShowCaption(True)
    line.SetCaptionPosition( LineAnnot.e_Top )
    line.SetBorderStyle( BorderStyle( BorderStyle.e_dashed, 2, 0, 0, [2.0, 2.0] ) )
    line.RefreshAppearance()
    page.AnnotPushBack(line)
    
    line=LineAnnot.Create(doc.GetSDFDoc(), Rect(347, 377, 600, 600))
    line.SetStartPoint( Point(385, 410 ) )
    line.SetEndPoint( Point(540,555) )
    line.SetStartStyle(LineAnnot.e_Circle)
    line.SetEndStyle(LineAnnot.e_OpenArrow)
    line.SetColor(ColorPt(1, 0, 0), 3)
    line.SetInteriorColor(ColorPt(0, 1, 0), 3)
    line.SetContents( "Inline Caption" )
    line.SetShowCaption(True)
    line.SetCaptionPosition( LineAnnot.e_Inline )
    line.SetLeaderLineExtensionLength( 4. )
    line.SetLeaderLineLength( -12. )
    line.SetLeaderLineOffset( 2. )
    line.RefreshAppearance()
    page.AnnotPushBack(line)
    
    line=LineAnnot.Create(doc.GetSDFDoc(), Rect(10, 400, 200, 600))
    line.SetStartPoint( Point(25, 426 ) )
    line.SetEndPoint( Point(180,555) )
    line.SetStartStyle(LineAnnot.e_Circle)
    line.SetEndStyle(LineAnnot.e_Square)
    line.SetColor(ColorPt(0, 0, 1), 3)
    line.SetInteriorColor(ColorPt(1, 0, 0), 3)
    line.SetContents("Offset Caption")
    line.SetShowCaption(True)
    line.SetCaptionPosition( LineAnnot.e_Top )
    line.SetTextHOffset( -60 )
    line.SetTextVOffset( 10 )
    line.RefreshAppearance()
    page.AnnotPushBack(line)
    
    line=LineAnnot.Create(doc.GetSDFDoc(), Rect(200, 10, 400, 70))
    line.SetStartPoint( Point(220, 25 ) )
    line.SetEndPoint( Point(370,60) )
    line.SetStartStyle(LineAnnot.e_Butt)
    line.SetEndStyle(LineAnnot.e_OpenArrow)
    line.SetColor(ColorPt(0, 0, 1), 3)
    line.SetContents( "Regular Caption" )
    line.SetShowCaption(True)
    line.SetCaptionPosition( LineAnnot.e_Top )
    line.RefreshAppearance()
    page.AnnotPushBack(line)
    
    line=LineAnnot.Create(doc.GetSDFDoc(), Rect(200, 70, 400, 130))
    line.SetStartPoint( Point(220, 111 ) )
    line.SetEndPoint( Point(370,78) )
    line.SetStartStyle(LineAnnot.e_Circle)
    line.SetEndStyle(LineAnnot.e_Diamond)
    line.SetContents( "Circle to Diamond" )
    line.SetColor(ColorPt(0, 0, 1), 3)
    line.SetInteriorColor(ColorPt(0, 1, 0), 3)
    line.SetShowCaption(True)
    line.SetCaptionPosition( LineAnnot.e_Top )
    line.RefreshAppearance()
    page.AnnotPushBack(line)
    
    line=LineAnnot.Create(doc.GetSDFDoc(), Rect(10, 100, 160, 200))
    line.SetStartPoint( Point(15, 110 ) )
    line.SetEndPoint( Point(150, 190) )
    line.SetStartStyle(LineAnnot.e_Slash)
    line.SetEndStyle(LineAnnot.e_ClosedArrow)
    line.SetContents( "Slash to CArrow" )
    line.SetColor(ColorPt(1, 0, 0), 3)
    line.SetInteriorColor(ColorPt(0, 1, 1), 3)
    line.SetShowCaption(True)
    line.SetCaptionPosition( LineAnnot.e_Top )
    line.RefreshAppearance()
    page.AnnotPushBack(line)
    
    line=LineAnnot.Create(doc.GetSDFDoc(), Rect( 270, 270, 570, 433 ))
    line.SetStartPoint( Point(300, 400 ) )
    line.SetEndPoint( Point(550, 300) )
    line.SetStartStyle(LineAnnot.e_RClosedArrow)
    line.SetEndStyle(LineAnnot.e_ROpenArrow)
    line.SetContents( "ROpen & RClosed arrows" )
    line.SetColor(ColorPt(0, 0, 1), 3)
    line.SetInteriorColor(ColorPt(0, 1, 0), 3)
    line.SetShowCaption(True)
    line.SetCaptionPosition( LineAnnot.e_Top )
    line.RefreshAppearance()
    page.AnnotPushBack(line)

    line=LineAnnot.Create(doc.GetSDFDoc(), Rect( 195, 395, 205, 505 ))
    line.SetStartPoint( Point(200, 400 ) )
    line.SetEndPoint( Point(200, 500) )
    line.RefreshAppearance()
    page.AnnotPushBack(line)
    
    line=LineAnnot.Create(doc.GetSDFDoc(), Rect( 55, 299, 150, 301 ))
    line.SetStartPoint( Point(55, 300 ) )
    line.SetEndPoint( Point(155, 300) )
    line.SetStartStyle(LineAnnot.e_Circle)
    line.SetEndStyle(LineAnnot.e_Circle)
    line.SetContents( "Caption that's longer than its line." )
    line.SetColor(ColorPt(1, 0, 1), 3)
    line.SetInteriorColor(ColorPt(0, 1, 0), 3)
    line.SetShowCaption(True)
    line.SetCaptionPosition( LineAnnot.e_Top )
    line.RefreshAppearance()
    page.AnnotPushBack(line)
    
    line=LineAnnot.Create(doc.GetSDFDoc(), Rect( 300, 200, 390, 234 ))
    line.SetStartPoint( Point(310, 210 ) )
    line.SetEndPoint( Point(380, 220) )
    line.SetColor(ColorPt(0, 0, 0), 3)
    line.RefreshAppearance()
    page.AnnotPushBack(line)

    page3 = doc.PageCreate(Rect(0, 0, 600, 600))
    ew.Begin(page3)     # begin writing to the page
    ew.End()   # save changes to the current page
    doc.PagePushBack(page3)

    circle=Circle.Create(doc.GetSDFDoc(), Rect( 300, 300, 390, 350 ))
    circle.SetColor(ColorPt(0, 0, 0), 3)
    circle.RefreshAppearance()
    page3.AnnotPushBack(circle)
    
    circle=Circle.Create(doc.GetSDFDoc(), Rect( 100, 100, 200, 200 ))
    circle.SetColor(ColorPt(0, 1, 0), 3)
    circle.SetInteriorColor(ColorPt(0, 0, 1), 3)
    circle.SetBorderStyle( BorderStyle( BorderStyle.e_dashed, 3, 0, 0, [2, 4] ) )
    circle.SetPadding( 2 )
    circle.RefreshAppearance()
    page3.AnnotPushBack(circle)

    sq = Square.Create( doc.GetSDFDoc(), Rect(10,200, 80, 300 ) )
    sq.SetColor(ColorPt(0, 0, 0), 3)
    sq.RefreshAppearance()
    page3.AnnotPushBack( sq )

    sq = Square.Create( doc.GetSDFDoc(), Rect(500,200, 580, 300 ) )
    sq.SetColor(ColorPt(1, 0, 0), 3)
    sq.SetInteriorColor(ColorPt(0, 1, 1), 3)
    sq.SetBorderStyle( BorderStyle( BorderStyle.e_dashed, 6, 0, 0, [4, 2] ) )
    sq.SetPadding( 4 )
    sq.RefreshAppearance()
    page3.AnnotPushBack( sq )
    
    poly = Polygon.Create(doc.GetSDFDoc(), Rect(5, 500, 125, 590))
    poly.SetColor(ColorPt(1, 0, 0), 3)
    poly.SetInteriorColor(ColorPt(1, 1, 0), 3)
    poly.SetVertex(0, Point(12,510) )
    poly.SetVertex(1, Point(100,510) )
    poly.SetVertex(2, Point(100,555) )
    poly.SetVertex(3, Point(35,544) )
    poly.SetBorderStyle( BorderStyle( BorderStyle.e_solid, 4, 0, 0 ) )
    poly.SetPadding( 4 )
    poly.RefreshAppearance()
    page3.AnnotPushBack( poly )
    
    poly = PolyLine.Create(doc.GetSDFDoc(), Rect(400, 10, 500, 90))
    poly.SetColor(ColorPt(1, 0, 0), 3)
    poly.SetInteriorColor(ColorPt(0, 1, 0), 3)
    poly.SetVertex(0, Point(405,20) )
    poly.SetVertex(1, Point(440,40) )
    poly.SetVertex(2, Point(410,60) )
    poly.SetVertex(3, Point(470,80) )
    poly.SetBorderStyle( BorderStyle( BorderStyle.e_solid, 2, 0, 0 ) )
    poly.SetPadding( 4 )
    poly.SetStartStyle( LineAnnot.e_RClosedArrow )
    poly.SetEndStyle( LineAnnot.e_ClosedArrow )
    poly.RefreshAppearance()
    page3.AnnotPushBack( poly )

    lk = Link.Create( doc.GetSDFDoc(), Rect(5,5,55,24) )
    lk.RefreshAppearance()
    page3.AnnotPushBack( lk )

    page4 = doc.PageCreate(Rect(0, 0, 600, 600))
    ew.Begin(page4)    # begin writing to the page
    ew.End()  # save changes to the current page
    doc.PagePushBack(page4)
    
    ew.Begin( page4 )
    font = Font.Create(doc.GetSDFDoc(), Font.e_helvetica)
    element = eb.CreateTextBegin( font, 16 )
    element.SetPathFill(True)
    ew.WriteElement(element)
    element = eb.CreateTextRun( "Some random text on the page", font, 16 )
    element.SetTextMatrix(1, 0, 0, 1, 100, 500 )
    ew.WriteElement(element)
    ew.WriteElement( eb.CreateTextEnd() )
    ew.End()

    hl = HighlightAnnot.Create( doc.GetSDFDoc(), Rect(100,490,150,515) )
    hl.SetColor( ColorPt(0,1,0), 3 )
    hl.RefreshAppearance()
    page4.AnnotPushBack( hl )

    sq = Squiggly.Create( doc.GetSDFDoc(), Rect(100,450,250,600) )
    sq.SetQuadPoint( 0, QuadPoint( Point( 122,455), Point(240, 545), Point(230, 595), Point(101,500 ) ) )
    sq.RefreshAppearance()
    page4.AnnotPushBack( sq )

    cr = Caret.Create( doc.GetSDFDoc(), Rect(100,40,129,69) )
    cr.SetColor( ColorPt(0,0,1), 3 )
    cr.SetSymbol( "P" )
    cr.RefreshAppearance()
    page4.AnnotPushBack( cr )
    
    page5 = doc.PageCreate(Rect(0, 0, 600, 600))
    ew.Begin(page5)    # begin writing to the page
    ew.End()  # save changes to the current page
    doc.PagePushBack(page5)
    fs = FileSpec.Create( doc.GetSDFDoc(), (input_path + "butterfly.png"), False )
    page6 = doc.PageCreate(Rect(0, 0, 600, 600))
    ew.Begin(page6)    # begin writing to the page
    ew.End()  # save changes to the current page
    doc.PagePushBack(page6)
    
        
    txt = Text.Create( doc.GetSDFDoc(), Point(10, 20) )
    txt.SetIcon( "UserIcon" )
    txt.SetContents( "User defined icon, unrecognized by appearance generator" )
    txt.SetColor( ColorPt(0,1,0) )
    txt.RefreshAppearance()
    page6.AnnotPushBack( txt )
    
    ink = Ink.Create( doc.GetSDFDoc(), Rect( 100, 400, 200, 550 ) )
    ink.SetColor( ColorPt(0,0,1) )
    ink.SetPoint( 1, 3, Point( 220, 505) )
    ink.SetPoint( 1, 0, Point( 100, 490) )
    ink.SetPoint( 0, 1, Point( 120, 410) )
    ink.SetPoint( 0, 0, Point( 100, 400) )
    ink.SetPoint( 1, 2, Point( 180, 490) )
    ink.SetPoint( 1, 1, Point( 140, 440) )        
    ink.SetBorderStyle( BorderStyle( BorderStyle.e_solid, 3, 0, 0  ) )
    ink.RefreshAppearance()
    page6.AnnotPushBack( ink )
    
    page7 = doc.PageCreate(Rect(0, 0, 600, 600))
    ew.Begin(page7)    # begin writing to the page
    ew.End()  # save changes to the current page
    doc.PagePushBack(page7)
    
    snd = Sound.Create( doc.GetSDFDoc(), Rect( 100, 500, 120, 520 ) )
    snd.SetColor(  ColorPt(1,1,0) )
    snd.SetIcon( Sound.e_Speaker )
    snd.RefreshAppearance()
    page7.AnnotPushBack( snd )
    
    snd = Sound.Create( doc.GetSDFDoc(), Rect( 200, 500, 220, 520 ) )
    snd.SetColor(  ColorPt(1,1,0) )
    snd.SetIcon( Sound.e_Mic )
    snd.RefreshAppearance()
    page7.AnnotPushBack( snd )
    
    page8 = doc.PageCreate(Rect(0, 0, 600, 600))
    ew.Begin(page8)    # begin writing to the page
    ew.End()  # save changes to the current page
    doc.PagePushBack(page8)
    
    ipage = 0
    while ipage<2:
        px = 5
        py = 520
        istamp = RubberStamp.e_Approved
        while istamp <= RubberStamp.e_Draft:
            st = RubberStamp.Create(doc.GetSDFDoc(), Rect(1,1,100,100))
            st.SetIcon( istamp )
            st.SetContents( st.GetIconName() )
            st.SetRect( Rect(px, py, px+100, py+25 ) )
            py -= 100
            if py < 0:
                py = 520
                px+=200
            if ipage == 0:
                #page7.AnnotPushBack(st)
                pass
            else:
                page8.AnnotPushBack( st )
                st.RefreshAppearance()
            istamp = istamp + 1
        ipage = ipage + 1
    
    st = RubberStamp.Create( doc.GetSDFDoc(), Rect(400,5,550,45) )
    st.SetIcon( "UserStamp" )
    st.SetContents( "User defined stamp" )
    page8.AnnotPushBack( st )
    st.RefreshAppearance()
    
if __name__ == '__main__':
    PDFNet.Initialize(LicenseKey)
    
    output_path = "../../TestFiles/Output/"
    input_path = "../../TestFiles/"
    
    doc = PDFDoc(input_path + "numbered.pdf")
    doc.InitSecurityHandler()
    
    # An example of using SDF/Cos API to add any type of annotations.
    AnnotationLowLevelAPI(doc)
    doc.Save(output_path + "annotation_test1.pdf", SDFDoc.e_remove_unused)
    print("Done. Results saved in annotation_test1.pdf")
    
    # An example of using the high-level PDFNet API to read existing annotations,
    # to edit existing annotations, and to create new annotation from scratch.
    AnnotationHighLevelAPI(doc)
    doc.Save((output_path + "annotation_test2.pdf"), SDFDoc.e_linearized)
    doc.Close()
    print("Done. Results saved in annotation_test2.pdf")
    
    doc1 = PDFDoc()
    CreateTestAnnots(doc1)
    outfname = output_path + "new_annot_test_api.pdf"
    doc1.Save(outfname, SDFDoc.e_linearized)
    print("Saved new_annot_test_api.pdf")
    PDFNet.Terminate()
```

{% endcode %}
{% endtab %}

{% tab title="Ruby" %}
{% code lineNumbers="true" %}

```ruby
#---------------------------------------------------------------------------------------
# Copyright (c) 2001-2023 by Apryse Software Inc. All Rights Reserved.
# Consult LICENSE.txt regarding license information.
#---------------------------------------------------------------------------------------

require '../../../PDFNetC/Lib/PDFNetRuby'
include PDFNetRuby
require '../../LicenseKey/RUBY/LicenseKey'

$stdout.sync = true

$output_path = "../../TestFiles/Output/"
$input_path = "../../TestFiles/"

def FloatToStr(float)
	if float.to_i() == float.to_f()
		return float.to_i().to_s()
	else
		return float.to_f().to_s()
	end
end

def AnnotationHighLevelAPI(doc)
	# The following code snippet traverses all annotations in the document
	puts "Traversing all annotations in the document..."
	page_num = 1
	itr = doc.GetPageIterator()
	
	while itr.HasNext() do
		puts "Page " + page_num.to_s() + ": "
		page_num = page_num + 1
		page = itr.Current()
		num_annots = page.GetNumAnnots()
		i = 0
		while i < num_annots do
			annot = page.GetAnnot(i)
			if !(annot.IsValid())
				i = i + 1
				next
			end
			puts "Annot Type: " + annot.GetSDFObj().Get("Subtype").Value().GetName()
			
			bbox = annot.GetRect()
			puts "  Position: " + FloatToStr(bbox.x1.to_s()) + 
				  ", " + FloatToStr(bbox.y1.to_s()) +
				  ", " + FloatToStr(bbox.x2.to_s()) + 
				  ", " + FloatToStr(bbox.y2.to_s())
			
			type = annot.GetType()			
			case type
			when Annot::E_Link
				link = Link.new(annot)
				action = link.GetAction()
				if !(action.IsValid())
					i = i + 1
					next
				end
				if action.GetType() == Action::E_GoTo
					dest = action.GetDest()
					if !(dest.IsValid())
						puts "  Destination is not valid."
					else
						page_n = dest.GetPage().GetIndex()
						puts "  Links to: page number " + page_n.to_s() + " in this document"
					end
				elsif action.GetType() == Action::E_URI
					uri = action.GetSDFObj().Get("URI").Value().GetAsPDFText()
					puts "  Links to: " + uri.to_s()
				end
			when Annot::E_Widget
			when Annot::E_FileAttachment
			end
			i = i + 1
		end
		itr.Next()
	end

	# Use the high-level API to create new annotations.		
	first_page = doc.GetPage(1)
	
	# Create a hyperlink...
	hyperlink = Link.Create(doc.GetSDFDoc(), Rect.new(85, 570, 503, 524), Action.CreateURI(doc.GetSDFDoc(), "http://www.pdftron.com"))
	first_page.AnnotPushBack(hyperlink)
	
	# Create an intra-document link...
	goto_page_3 = Action.CreateGoto(Destination.CreateFitH(doc.GetPage(3), 0))
	link = Link.Create(doc.GetSDFDoc(), Rect.new(85, 458, 503, 502), goto_page_3)
	link.SetColor(ColorPt.new(0, 0, 1))
	
	# Add the new annotation to the first page
	first_page.AnnotPushBack(link) 
	
	# Create a stamp annotation ...
	stamp = RubberStamp.Create(doc.GetSDFDoc(), Rect.new(30, 30, 300, 200))
	stamp.SetIcon("Draft")
	first_page.AnnotPushBack(stamp)

	# Create a file attachment annotation (embed the 'peppers.jpg').
	file_attach = FileAttachment.Create(doc.GetSDFDoc(), Rect.new(80, 280, 108, 320), $input_path + "peppers.jpg")
	first_page.AnnotPushBack(file_attach)

	ink = Ink.Create(doc.GetSDFDoc(), Rect.new(110, 10, 300, 200))
	pt3 = Point.new(110, 10)
	pt3.x = 110 
	pt3.y = 10
	ink.SetPoint(0, 0, pt3)
	pt3.x = 150 
	pt3.y = 50
	ink.SetPoint(0, 1, pt3)
	pt3.x = 190 
	pt3.y = 60
	ink.SetPoint(0, 2, pt3)
	pt3.x = 180 
	pt3.y = 90
	ink.SetPoint(1, 0, pt3)
	pt3.x = 190 
	pt3.y = 95
	ink.SetPoint(1, 1, pt3)
	pt3.x = 200 
	pt3.y = 100
	ink.SetPoint(1, 2, pt3)
	pt3.x = 166 
	pt3.y = 86
	ink.SetPoint(2, 0, pt3)
	pt3.x = 196 
	pt3.y = 96
	ink.SetPoint(2, 1, pt3)
	pt3.x = 221 
	pt3.y = 121
	ink.SetPoint(2, 2, pt3)
	pt3.x = 288 
	pt3.y = 188
	ink.SetPoint(2, 3, pt3)
	ink.SetColor(ColorPt.new(0, 1, 1), 3)
	first_page.AnnotPushBack(ink)
end

def AnnotationLowLevelAPI(doc)
	itr = doc.GetPageIterator()
	page = itr.Current()
	annots = page.GetAnnots()
	
	if annots.nil?
		# If there are no annotations, create a new annotation 
		# array for the page.
		annots = doc.CreateIndirectArray()
		page.GetSDFObj().Put("Annots", annots)
	end

	# Create a Text annotation
	annot = doc.CreateIndirectDict()
	annot.PutName("Subtype", "Text")
	annot.PutBool("Open", true)
	annot.PutString("Contents", "The quick brown fox ate the lazy mouse.")
	annot.PutRect("Rect", 266, 116, 430, 204)

	# Insert the annotation in the page annotation array
	annots.PushBack(annot)   
	
	# Create a Link annotation
	link1 = doc.CreateIndirectDict()
	link1.PutName("Subtype", "Link")
	dest = Destination.CreateFit(doc.GetPage(2))
	link1.Put("Dest", dest.GetSDFObj())
	link1.PutRect("Rect", 85, 705, 503, 661)
	annots.PushBack(link1)

	# Create another Link annotation
	link2 = doc.CreateIndirectDict()
	link2.PutName("Subtype", "Link")
	dest2 = Destination.CreateFit((doc.GetPage(3)))
	link2.Put("Dest", dest2.GetSDFObj())
	link2.PutRect("Rect", 85, 638, 503, 594)
	annots.PushBack(link2)
	
	# Note that PDFNet API can be used to modify existing annotations. 
	# In the following example we will modify the second link annotation 
	# (link2) so that it points to the 10th page. We also use a different 
	# destination page fit type.
	
	# link2 = annots.GetAt(annots.Size()-1)
	link2.Put("Dest", Destination.CreateXYZ(doc.GetPage(10), 100, 792-70, 10).GetSDFObj())
	
	# Create a third link annotation with a hyperlink action (all other 
	# annotation types can be created in a similar way)
	link3 = doc.CreateIndirectDict()
	link3.PutName("Subtype", "Link")
	link3.PutRect("Rect", 85, 570, 503, 524)
	
	# Create a URI action 
	action = link3.PutDict("A")
	action.PutName("S", "URI")
	action.PutString("URI", "http://www.pdftron.com")
	
	annots.PushBack(link3)
end
	
def CreateTestAnnots(doc)
	ew = ElementWriter.new()
	eb = ElementBuilder.new()
	
	first_page = doc.PageCreate(Rect.new(0, 0, 600, 600))
	doc.PagePushBack(first_page)
	ew.Begin(first_page, ElementWriter::E_overlay, false )   # begin writing to this page
	ew.End()	# save changes to the current page
	
	# Test of a free text annotation.
	txtannot = FreeText.Create( doc.GetSDFDoc(), Rect.new(10, 400, 160, 570)  )
	txtannot.SetContents( "\n\nSome swift brown fox snatched a gray hare out " +
						  "of the air by freezing it with an angry glare." +
						  "\n\nAha!\n\nAnd there was much rejoicing!"	)
	txtannot.SetBorderStyle( BorderStyle.new( BorderStyle::E_solid, 1, 10, 20 ), false )
	txtannot.SetQuaddingFormat(0)
	first_page.AnnotPushBack(txtannot)
	txtannot.RefreshAppearance()
	
	txtannot = FreeText.Create( doc.GetSDFDoc(), Rect.new(100, 100, 350, 500)  )
	txtannot.SetContentRect( Rect.new( 200, 200, 350, 500 ) )
	txtannot.SetContents( "\n\nSome swift brown fox snatched a gray hare out of the air " +
				"by freezing it with an angry glare." +
				"\n\nAha!\n\nAnd there was much rejoicing!")
	txtannot.SetCalloutLinePoints( Point.new(200,300), Point.new(150,290), Point.new(110,110) )
	txtannot.SetBorderStyle( BorderStyle.new( BorderStyle::E_solid, 1, 10, 20 ), false )
	txtannot.SetEndingStyle( LineAnnot::E_ClosedArrow )
	txtannot.SetColor( ColorPt.new( 0, 1, 0 ) )
	txtannot.SetQuaddingFormat(1)
	first_page.AnnotPushBack(txtannot)
	txtannot.RefreshAppearance()
	
	txtannot = FreeText.Create(doc.GetSDFDoc(), Rect.new(400, 10, 550, 400))	
	txtannot.SetContents( "\n\nSome swift brown fox snatched a gray hare out of the air " +
				"by freezing it with an angry glare." +
				"\n\nAha!\n\nAnd there was much rejoicing!")
	txtannot.SetBorderStyle( BorderStyle.new( BorderStyle::E_solid, 1, 10, 20 ), false )
	txtannot.SetColor( ColorPt.new( 0, 0, 1 ) )
	txtannot.SetOpacity( 0.2 )
	txtannot.SetQuaddingFormat(2)
	first_page.AnnotPushBack(txtannot)
	txtannot.RefreshAppearance()
	
	page= doc.PageCreate(Rect.new(0, 0, 600, 600))
	doc.PagePushBack(page)
	ew.Begin(page, ElementWriter::E_overlay, false )	# begin writing to this page
	eb.Reset()	# Reset the GState to default
	ew.End()	# save changes to the current page
	
	# Create a Line annotation...
	line=LineAnnot.Create(doc.GetSDFDoc(), Rect.new(250, 250, 400, 400))
	line.SetStartPoint( Point.new(350, 270 ) )
	line.SetEndPoint( Point.new(260,370) )
	line.SetStartStyle(LineAnnot::E_Square)
	line.SetEndStyle(LineAnnot::E_Circle)
	line.SetColor(ColorPt.new(0.3, 0.5, 0), 3)
	line.SetContents( "Dashed Captioned" )
	line.SetShowCaption(true)
	line.SetCaptionPosition( LineAnnot::E_Top )
	line.SetBorderStyle( BorderStyle.new( BorderStyle::E_dashed, 2, 0, 0, [2.0, 2.0] ) )
	line.RefreshAppearance()
	page.AnnotPushBack(line)
	
	line=LineAnnot.Create(doc.GetSDFDoc(), Rect.new(347, 377, 600, 600))
	line.SetStartPoint( Point.new(385, 410 ) )
	line.SetEndPoint( Point.new(540,555) )
	line.SetStartStyle(LineAnnot::E_Circle)
	line.SetEndStyle(LineAnnot::E_OpenArrow)
	line.SetColor(ColorPt.new(1, 0, 0), 3)
	line.SetInteriorColor(ColorPt.new(0, 1, 0), 3)
	line.SetContents( "Inline Caption" )
	line.SetShowCaption(true)
	line.SetCaptionPosition( LineAnnot::E_Inline )
	line.SetLeaderLineExtensionLength( 4 )
	line.SetLeaderLineLength( -12 )
	line.SetLeaderLineOffset( 2 )
	line.RefreshAppearance()
	page.AnnotPushBack(line)
	
	line=LineAnnot.Create(doc.GetSDFDoc(), Rect.new(10, 400, 200, 600))
	line.SetStartPoint( Point.new(25, 426 ) )
	line.SetEndPoint( Point.new(180,555) )
	line.SetStartStyle(LineAnnot::E_Circle)
	line.SetEndStyle(LineAnnot::E_Square)
	line.SetColor(ColorPt.new(0, 0, 1), 3)
	line.SetInteriorColor(ColorPt.new(1, 0, 0), 3)
	line.SetContents("Offset Caption")
	line.SetShowCaption(true)
	line.SetCaptionPosition( LineAnnot::E_Top )
	line.SetTextHOffset( -60 )
	line.SetTextVOffset( 10 )
	line.RefreshAppearance()
	page.AnnotPushBack(line)
	
	line=LineAnnot.Create(doc.GetSDFDoc(), Rect.new(200, 10, 400, 70))
	line.SetStartPoint( Point.new(220, 25 ) )
	line.SetEndPoint( Point.new(370,60) )
	line.SetStartStyle(LineAnnot::E_Butt)
	line.SetEndStyle(LineAnnot::E_OpenArrow)
	line.SetColor(ColorPt.new(0, 0, 1), 3)
	line.SetContents( "Regular Caption" )
	line.SetShowCaption(true)
	line.SetCaptionPosition( LineAnnot::E_Top )
	line.RefreshAppearance()
	page.AnnotPushBack(line)
	
	line=LineAnnot.Create(doc.GetSDFDoc(), Rect.new(200, 70, 400, 130))
	line.SetStartPoint( Point.new(220, 111 ) )
	line.SetEndPoint( Point.new(370,78) )
	line.SetStartStyle(LineAnnot::E_Circle)
	line.SetEndStyle(LineAnnot::E_Diamond)
	line.SetContents( "Circle to Diamond" )
	line.SetColor(ColorPt.new(0, 0, 1), 3)
	line.SetInteriorColor(ColorPt.new(0, 1, 0), 3)
	line.SetShowCaption(true)
	line.SetCaptionPosition( LineAnnot::E_Top )
	line.RefreshAppearance()
	page.AnnotPushBack(line)
	
	line=LineAnnot.Create(doc.GetSDFDoc(), Rect.new(10, 100, 160, 200))
	line.SetStartPoint( Point.new(15, 110 ) )
	line.SetEndPoint( Point.new(150, 190) )
	line.SetStartStyle(LineAnnot::E_Slash)
	line.SetEndStyle(LineAnnot::E_ClosedArrow)
	line.SetContents( "Slash to CArrow" )
	line.SetColor(ColorPt.new(1, 0, 0), 3)
	line.SetInteriorColor(ColorPt.new(0, 1, 1), 3)
	line.SetShowCaption(true)
	line.SetCaptionPosition( LineAnnot::E_Top )
	line.RefreshAppearance()
	page.AnnotPushBack(line)
	
	line=LineAnnot.Create(doc.GetSDFDoc(), Rect.new( 270, 270, 570, 433 ))
	line.SetStartPoint( Point.new(300, 400 ) )
	line.SetEndPoint( Point.new(550, 300) )
	line.SetStartStyle(LineAnnot::E_RClosedArrow)
	line.SetEndStyle(LineAnnot::E_ROpenArrow)
	line.SetContents( "ROpen & RClosed arrows" )
	line.SetColor(ColorPt.new(0, 0, 1), 3)
	line.SetInteriorColor(ColorPt.new(0, 1, 0), 3)
	line.SetShowCaption(true)
	line.SetCaptionPosition( LineAnnot::E_Top )
	line.RefreshAppearance()
	page.AnnotPushBack(line)

	line=LineAnnot.Create(doc.GetSDFDoc(), Rect.new( 195, 395, 205, 505 ))
	line.SetStartPoint( Point.new(200, 400 ) )
	line.SetEndPoint( Point.new(200, 500) )
	line.RefreshAppearance()
	page.AnnotPushBack(line)
	
	line=LineAnnot.Create(doc.GetSDFDoc(), Rect.new( 55, 299, 150, 301 ))
	line.SetStartPoint( Point.new(55, 300 ) )
	line.SetEndPoint( Point.new(155, 300) )
	line.SetStartStyle(LineAnnot::E_Circle)
	line.SetEndStyle(LineAnnot::E_Circle)
	line.SetContents( "Caption that's longer than its line." )
	line.SetColor(ColorPt.new(1, 0, 1), 3)
	line.SetInteriorColor(ColorPt.new(0, 1, 0), 3)
	line.SetShowCaption(true)
	line.SetCaptionPosition( LineAnnot::E_Top )
	line.RefreshAppearance()
	page.AnnotPushBack(line)
	
	line=LineAnnot.Create(doc.GetSDFDoc(), Rect.new( 300, 200, 390, 234 ))
	line.SetStartPoint( Point.new(310, 210 ) )
	line.SetEndPoint( Point.new(380, 220) )
	line.SetColor(ColorPt.new(0, 0, 0), 3)
	line.RefreshAppearance()
	page.AnnotPushBack(line)

	page3 = doc.PageCreate(Rect.new(0, 0, 600, 600))
	ew.Begin(page3)	# begin writing to the page
	ew.End()	# save changes to the current page
	doc.PagePushBack(page3)

	circle=Circle.Create(doc.GetSDFDoc(), Rect.new( 300, 300, 390, 350 ))
	circle.SetColor(ColorPt.new(0, 0, 0), 3)
	circle.RefreshAppearance()
	page3.AnnotPushBack(circle)
	
	circle=Circle.Create(doc.GetSDFDoc(), Rect.new( 100, 100, 200, 200 ))
	circle.SetColor(ColorPt.new(0, 1, 0), 3)
	circle.SetInteriorColor(ColorPt.new(0, 0, 1), 3)
	circle.SetBorderStyle( BorderStyle.new( BorderStyle::E_dashed, 3, 0, 0, [2, 4] ) )
	circle.SetPadding( 2 )
	circle.RefreshAppearance()
	page3.AnnotPushBack(circle)

	sq = Square.Create( doc.GetSDFDoc(), Rect.new(10,200, 80, 300 ) )
	sq.SetColor(ColorPt.new(0, 0, 0), 3)
	sq.RefreshAppearance()
	page3.AnnotPushBack( sq )

	sq = Square.Create( doc.GetSDFDoc(), Rect.new(500,200, 580, 300 ) )
	sq.SetColor(ColorPt.new(1, 0, 0), 3)
	sq.SetInteriorColor(ColorPt.new(0, 1, 1), 3)
	sq.SetBorderStyle( BorderStyle.new( BorderStyle::E_dashed, 6, 0, 0, [4, 2] ) )
	sq.SetPadding( 4 )
	sq.RefreshAppearance()
	page3.AnnotPushBack( sq )
	
	poly = Polygon.Create(doc.GetSDFDoc(), Rect.new(5, 500, 125, 590))
	poly.SetColor(ColorPt.new(1, 0, 0), 3)
	poly.SetInteriorColor(ColorPt.new(1, 1, 0), 3)
	poly.SetVertex(0, Point.new(12,510) )
	poly.SetVertex(1, Point.new(100,510) )
	poly.SetVertex(2, Point.new(100,555) )
	poly.SetVertex(3, Point.new(35,544) )
	poly.SetBorderStyle( BorderStyle.new( BorderStyle::E_solid, 4, 0, 0 ) )
	poly.SetPadding( 4 )
	poly.RefreshAppearance()
	page3.AnnotPushBack( poly )
	
	poly = PolyLine.Create(doc.GetSDFDoc(), Rect.new(400, 10, 500, 90))
	poly.SetColor(ColorPt.new(1, 0, 0), 3)
	poly.SetInteriorColor(ColorPt.new(0, 1, 0), 3)
	poly.SetVertex(0, Point.new(405,20) )
	poly.SetVertex(1, Point.new(440,40) )
	poly.SetVertex(2, Point.new(410,60) )
	poly.SetVertex(3, Point.new(470,80) )
	poly.SetBorderStyle( BorderStyle.new( BorderStyle::E_solid, 2, 0, 0 ) )
	poly.SetPadding( 4 )
	poly.SetStartStyle( LineAnnot::E_RClosedArrow )
	poly.SetEndStyle( LineAnnot::E_ClosedArrow )
	poly.RefreshAppearance()
	page3.AnnotPushBack( poly )

	lk = Link.Create( doc.GetSDFDoc(), Rect.new(5,5,55,24) )
	lk.RefreshAppearance()
	page3.AnnotPushBack( lk )

	page4 = doc.PageCreate(Rect.new(0, 0, 600, 600))
	ew.Begin(page4)	# begin writing to the page
	ew.End()  # save changes to the current page
	doc.PagePushBack(page4)
	
	ew.Begin( page4 )
	font = Font.Create(doc.GetSDFDoc(), Font::E_helvetica)
	element = eb.CreateTextBegin( font, 16 )
	element.SetPathFill(true)
	ew.WriteElement(element)
	element = eb.CreateTextRun( "Some random text on the page", font, 16 )
	element.SetTextMatrix(1, 0, 0, 1, 100, 500 )
	ew.WriteElement(element)
	ew.WriteElement( eb.CreateTextEnd() )
	ew.End()

	hl = HighlightAnnot.Create( doc.GetSDFDoc(), Rect.new(100,490,150,515) )
	hl.SetColor( ColorPt.new(0,1,0), 3 )
	hl.RefreshAppearance()
	page4.AnnotPushBack( hl )

	sq = Squiggly.Create( doc.GetSDFDoc(), Rect.new(100,450,250,600) )
	sq.SetQuadPoint( 0, QuadPoint.new( Point.new(122,455), Point.new(240, 545), Point.new(230, 595), Point.new(101,500 ) ) )
	sq.RefreshAppearance()
	page4.AnnotPushBack( sq )

	cr = Caret.Create( doc.GetSDFDoc(), Rect.new(100,40,129,69) )
	cr.SetColor( ColorPt.new(0,0,1), 3 )
	cr.SetSymbol( "P" )
	cr.RefreshAppearance()
	page4.AnnotPushBack( cr )
	
	page5 = doc.PageCreate(Rect.new(0, 0, 600, 600))
	ew.Begin(page5)	# begin writing to the page
	ew.End()  # save changes to the current page
	doc.PagePushBack(page5)
	fs = FileSpec.Create( doc.GetSDFDoc(), ($input_path + "butterfly.png"), false )
	page6 = doc.PageCreate(Rect.new(0, 0, 600, 600))
	ew.Begin(page6)	# begin writing to the page
	ew.End()  # save changes to the current page
	doc.PagePushBack(page6)
	
		
	txt = Text.Create( doc.GetSDFDoc(), Rect.new( 10, 20, 30, 40 ) )
	txt.SetIcon( "UserIcon" )
	txt.SetContents( "User defined icon, unrecognized by appearance generator" )
	txt.SetColor( ColorPt.new(0,1,0) )
	txt.RefreshAppearance()
	page6.AnnotPushBack( txt )
	
	ink = Ink.Create( doc.GetSDFDoc(), Rect.new( 100, 400, 200, 550 ) )
	ink.SetColor( ColorPt.new(0,0,1) )
	ink.SetPoint( 1, 3, Point.new( 220, 505) )
	ink.SetPoint( 1, 0, Point.new( 100, 490) )
	ink.SetPoint( 0, 1, Point.new( 120, 410) )
	ink.SetPoint( 0, 0, Point.new( 100, 400) )
	ink.SetPoint( 1, 2, Point.new( 180, 490) )
	ink.SetPoint( 1, 1, Point.new( 140, 440) )		
	ink.SetBorderStyle( BorderStyle.new( BorderStyle::E_solid, 3, 0, 0  ) )
	ink.RefreshAppearance()
	page6.AnnotPushBack( ink )
	
	page7 = doc.PageCreate(Rect.new(0, 0, 600, 600))
	ew.Begin(page7)	# begin writing to the page
	ew.End()  # save changes to the current page
	doc.PagePushBack(page7)
	
	snd = Sound.Create( doc.GetSDFDoc(), Rect.new( 100, 500, 120, 520 ) )
	snd.SetColor(  ColorPt.new(1,1,0) )
	snd.SetIcon( Sound::E_Speaker )
	snd.RefreshAppearance()
	page7.AnnotPushBack( snd )
	
	snd = Sound.Create( doc.GetSDFDoc(), Rect.new( 200, 500, 220, 520 ) )
	snd.SetColor(  ColorPt.new(1,1,0) )
	snd.SetIcon( Sound::E_Mic )
	snd.RefreshAppearance()
	page7.AnnotPushBack( snd )
	
	page8 = doc.PageCreate(Rect.new(0, 0, 600, 600))
	ew.Begin(page8)	# begin writing to the page
	ew.End()	# save changes to the current page
	doc.PagePushBack(page8)
	
	ipage = 0
	while ipage<2 do
		px = 5
		py = 520
		istamp = RubberStamp::E_Approved
		while istamp <= RubberStamp::E_Draft do
			st = RubberStamp.Create(doc.GetSDFDoc(), Rect.new(1,1,100,100))
			st.SetIcon( istamp )
			st.SetContents( st.GetIconName() )
			st.SetRect( Rect.new(px, py, px+100, py+25 ) )
			py -= 100
			if py < 0
				py = 520
				px+=200
			end
			if ipage == 0
				#page7.AnnotPushBack( st )
			else
				page8.AnnotPushBack( st )
				st.RefreshAppearance()
			end
			istamp = istamp + 1
		end
		ipage = ipage + 1
	end
	
	st = RubberStamp.Create( doc.GetSDFDoc(), Rect.new(400,5,550,45) )
	st.SetIcon( "UserStamp" )
	st.SetContents( "User defined stamp" )
	page8.AnnotPushBack( st )
	st.RefreshAppearance()
end

	PDFNet.Initialize(PDFTronLicense.Key)
	
	doc = PDFDoc.new($input_path + "numbered.pdf")
	doc.InitSecurityHandler()
	
	# An example of using SDF/Cos API to add any type of annotations.
	AnnotationLowLevelAPI(doc)
	doc.Save($output_path + "annotation_test1.pdf", SDFDoc::E_remove_unused)
	puts "Done. Results saved in annotation_test1.pdf"
	
	# An example of using the high-level PDFNet API to read existing annotations,
	# to edit existing annotations, and to create new annotation from scratch.
	AnnotationHighLevelAPI(doc)
	doc.Save(($output_path + "annotation_test2.pdf"), SDFDoc::E_linearized)
	doc.Close()
	puts "Done. Results saved in annotation_test2.pdf"
	
	doc1 = PDFDoc.new()
	CreateTestAnnots(doc1)
	outfname = $output_path + "new_annot_test_api.pdf"
	doc1.Save(outfname, SDFDoc::E_linearized)
	doc1.Close()
	PDFNet.Terminate
	puts "Saved new_annot_test_api.pdf"
```

{% endcode %}
{% endtab %}

{% tab title="VB" %}
{% code lineNumbers="true" %}

```vb
'
' Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
'
Imports pdftron
Imports pdftron.Common
Imports pdftron.Filters
Imports pdftron.SDF
Imports pdftron.PDF
Imports pdftron.PDF.Annots

Namespace AnnotationTestVB

    ''' <summary>
    ''' Summary description for Class1.
    ''' </summary>
    Class Class1

        Private Shared pdfNetLoader As pdftron.PDFNetLoader
        Shared Sub New()
            pdfNetLoader = pdftron.PDFNetLoader.Instance
        End Sub

        Private Shared Sub AnnotationHighLevelAPI(ByVal doc As PDFDoc)
            ' The following code snippet traverses all annotations in the document
            System.Console.WriteLine("Traversing all annotations in the document...")
            Dim uri As String
            Dim page_num As Integer = 1
            Dim itr As PageIterator = doc.GetPageIterator
            Do While itr.HasNext
                System.Console.WriteLine("Page " & page_num & ": ")
                page_num = page_num + 1
                Dim page As Page = itr.Current
                Dim num_annots As Integer = page.GetNumAnnots
                Dim i As Integer = 0
                Do While (i < num_annots)
                    Dim annot As Annot = page.GetAnnot(i)
                    If Not annot.IsValid Then
                        'TODO: Warning!!! continue If
                    End If

                    System.Console.WriteLine(("Annot Type: " & annot.GetSDFObj.Get("Subtype").Value.GetName))
                    Dim bbox As Rect = annot.GetRect
                    System.Console.WriteLine("  Position: " & bbox.x1 & ", " &
                                    bbox.y1 & ", " & bbox.x2 & ", " & bbox.y2)
                    Select Case (annot.GetType)
                        Case annot.Type.e_Link
                            Dim action As Action = New Link(annot).GetAction
                            If Not action.IsValid Then
                                'TODO: Warning!!! continue If
                            End If

                            If (action.GetType = action.Type.e_GoTo) Then
                                Dim dest As Destination = action.GetDest
                                If Not dest.IsValid Then
                                    System.Console.WriteLine("  Destination is not valid")
                                Else
                                    Dim pg_num As Integer = dest.GetPage.GetIndex
                                    System.Console.WriteLine("  Links to: page number " &
                                                    pg_num & " in this document")
                                End If

                            ElseIf (action.GetType = action.Type.e_URI) Then
                                uri = action.GetSDFObj.Get("URI").Value.GetAsPDFText
                                System.Console.WriteLine("  Links to: " & uri)
                            End If

                            ' ...
                        Case annot.Type.e_Widget
                        Case annot.Type.e_FileAttachment
                    End Select

                    i = (i + 1)
                Loop

                itr.Next()
            Loop

            ' Use the high-level API to create new annotations.
            Dim first_page As Page = doc.GetPage(1)
            ' Create a hyperlink...
            Dim hyperlink As Link = Link.Create(doc, New Rect(85, 570, 503, 524), Action.CreateURI(doc, "http://www.pdftron.com"))
            first_page.AnnotPushBack(hyperlink)
            ' Create an intra-document link...
            Dim goto_page_3 As Action = Action.CreateGoto(Destination.CreateFitH(doc.GetPage(3), 0))
            Dim lnk As Link = Link.Create(doc, New Rect(85, 458, 503, 502), goto_page_3)
            lnk.SetColor(New ColorPt(0, 0, 1))
            ' Add the new annotation to the first page
            first_page.AnnotPushBack(lnk)
            ' Create a stamp annotation ...
            Dim stamp As RubberStamp = RubberStamp.Create(doc, New Rect(30, 30, 300, 200))
            stamp.SetIcon("Draft")
            first_page.AnnotPushBack(stamp)
            ' Create a file attachment annotation (embed the 'peppers.jpg').
            Dim file_attach As FileAttachment = FileAttachment.Create(doc, New Rect(80, 280, 108, 320), (input_path + "peppers.jpg"))
            first_page.AnnotPushBack(file_attach)
            Dim inkobj As Ink = Ink.Create(doc, New Rect(110, 10, 300, 200))
            Dim pt3 As Point = New Point(110, 10)
            'pt3.x = 110; pt3.y = 10;
            inkobj.SetPoint(0, 0, pt3)
            pt3.x = 150
            pt3.y = 50
            inkobj.SetPoint(0, 1, pt3)
            pt3.x = 190
            pt3.y = 60
            inkobj.SetPoint(0, 2, pt3)
            pt3.x = 180
            pt3.y = 90
            inkobj.SetPoint(1, 0, pt3)
            pt3.x = 190
            pt3.y = 95
            inkobj.SetPoint(1, 1, pt3)
            pt3.x = 200
            pt3.y = 100
            inkobj.SetPoint(1, 2, pt3)
            pt3.x = 166
            pt3.y = 86
            inkobj.SetPoint(2, 0, pt3)
            pt3.x = 196
            pt3.y = 96
            inkobj.SetPoint(2, 1, pt3)
            pt3.x = 221
            pt3.y = 121
            inkobj.SetPoint(2, 2, pt3)
            pt3.x = 288
            pt3.y = 188
            inkobj.SetPoint(2, 3, pt3)
            inkobj.SetColor(New ColorPt(0, 1, 1), 3)
            first_page.AnnotPushBack(inkobj)
        End Sub

        Private Shared Sub AnnotationLowLevelAPI(ByVal doc As PDFDoc)
            Dim page As Page = doc.GetPage(1)
            Dim annots As Obj = page.GetAnnots
            If (annots Is Nothing) Then
                ' If there are no annotations, create a new annotation 
                ' array for the page.
                annots = doc.CreateIndirectArray
                page.GetSDFObj.Put("Annots", annots)
            End If

            ' Create the Text annotation
            Dim text_annot As Obj = doc.CreateIndirectDict
            text_annot.PutName("Subtype", "Text")
            text_annot.PutBool("Open", True)
            text_annot.PutString("Contents", "The quick brown fox ate the lazy mouse.")
            text_annot.PutRect("Rect", 266, 116, 430, 204)
            ' Insert the annotation in the page annotation array
            annots.PushBack(text_annot)
            ' Create a Link annotation
            Dim link1 As Obj = doc.CreateIndirectDict
            link1.PutName("Subtype", "Link")
            Dim dest As Destination = Destination.CreateFit(doc.GetPage(2))
            link1.Put("Dest", dest.GetSDFObj)
            link1.PutRect("Rect", 85, 705, 503, 661)
            annots.PushBack(link1)
            ' Create another Link annotation
            Dim link2 As Obj = doc.CreateIndirectDict
            link2.PutName("Subtype", "Link")
            Dim dest2 As Destination = Destination.CreateFit(doc.GetPage(3))
            link2.Put("Dest", dest2.GetSDFObj)
            link2.PutRect("Rect", 85, 638, 503, 594)
            annots.PushBack(link2)
            ' Note that PDFNet APi can be used to modify existing annotations. 
            ' In the following example we will modify the second link annotation 
            ' (link2) so that it points to the 10th page. We also use a different 
            ' destination page fit type.
            link2.Put("Dest", Destination.CreateXYZ(doc.GetPage(10), 100, (792 - 70), 10).GetSDFObj)
            ' Create a third link annotation with a hyperlink action (all other 
            ' annotation types can be created in a similar way)
            Dim link3 As Obj = doc.CreateIndirectDict
            link3.PutName("Subtype", "Link")
            link3.PutRect("Rect", 85, 570, 503, 524)
            ' Create a URI action
            Dim action As Obj = link3.PutDict("A")
            action.PutName("S", "URI")
            action.PutString("URI", "http://www.pdftron.com")
            annots.PushBack(link3)
        End Sub

        Private Shared Sub CreateTestAnnots(ByVal doc As PDFDoc)
            Dim ew As ElementWriter = New ElementWriter
            Dim eb As ElementBuilder = New ElementBuilder
            Dim element As Element
            Dim first_page As Page = doc.PageCreate(New Rect(0, 0, 600, 600))
            doc.PagePushBack(first_page)
            ew.Begin(first_page, ElementWriter.WriteMode.e_overlay, False)
            ' begin writing to this page
            ew.End()
            ' save changes to the current page
            '
            ' Test of a free text annotation.
            '
            Dim txtannot As FreeText = FreeText.Create(doc, New Rect(10, 400, 160, 570))
            txtannot.SetContents(ControlChars.Lf + ControlChars.Lf + "Some swift brown fox snatched a gray hare out of the air by freezing it with an angry glare." + ControlChars.Lf + ControlChars.Lf + "Aha!" + ControlChars.Lf + ControlChars.Lf + "And there was much rejoicing!")
            txtannot.SetBorderStyle(New Annot.BorderStyle(Annot.BorderStyle.Style.e_solid, 1, 10, 20))
            txtannot.SetQuaddingFormat(0)
            first_page.AnnotPushBack(txtannot)
            txtannot.RefreshAppearance()
            txtannot = FreeText.Create(doc, New Rect(100, 100, 350, 500))
            txtannot.SetContentRect(New Rect(200, 200, 350, 500))
            txtannot.SetContents(ControlChars.Lf + ControlChars.Lf + "Some swift brown fox snatched a gray hare out of the air by freezing it with an angry glare." + ControlChars.Lf + ControlChars.Lf + "Aha!" + ControlChars.Lf + ControlChars.Lf + "And there was much rejoicing!")
            txtannot.SetCalloutLinePoints(New Point(200, 300), New Point(150, 290), New Point(110, 110))
            txtannot.SetBorderStyle(New Annot.BorderStyle(Annot.BorderStyle.Style.e_solid, 1, 10, 20))
            txtannot.SetEndingStyle(Line.EndingStyle.e_ClosedArrow)
            txtannot.SetColor(New ColorPt(0, 1, 0))
            txtannot.SetQuaddingFormat(1)
            first_page.AnnotPushBack(txtannot)
            txtannot.RefreshAppearance()
            txtannot = FreeText.Create(doc, New Rect(400, 10, 550, 400))
            txtannot.SetContents(ControlChars.Lf + ControlChars.Lf + "Some swift brown fox snatched a gray hare out of the air by freezing it with an angry glare." + ControlChars.Lf + ControlChars.Lf + "Aha!" + ControlChars.Lf + ControlChars.Lf + "And there was much rejoicing!")
            txtannot.SetBorderStyle(New Annot.BorderStyle(Annot.BorderStyle.Style.e_solid, 1, 10, 20))
            txtannot.SetColor(New ColorPt(0, 0, 1))
            txtannot.SetOpacity(0.2)
            txtannot.SetQuaddingFormat(2)
            first_page.AnnotPushBack(txtannot)
            txtannot.RefreshAppearance()
            Dim page As Page = doc.PageCreate(New Rect(0, 0, 600, 600))
            doc.PagePushBack(page)
            ew.Begin(page, ElementWriter.WriteMode.e_overlay, False)
            ' begin writing to this page
            eb.Reset()
            ' Reset the GState to default
            ew.End()
            ' save changes to the current page
            'Create a Line annotation...
            Dim lineobj As Line = Line.Create(doc, New Rect(250, 250, 400, 400))
            lineobj.SetStartPoint(New Point(350, 270))
            lineobj.SetEndPoint(New Point(260, 370))
            lineobj.SetStartStyle(Line.EndingStyle.e_Square)
            lineobj.SetEndStyle(Line.EndingStyle.e_Circle)
            lineobj.SetColor(New ColorPt(0.3, 0.5, 0), 3)
            lineobj.SetContents("Dashed Captioned")
            lineobj.SetShowCaption(True)
            lineobj.SetCaptionPosition(Line.CapPos.e_Top)
            Dim dash() As Double = New Double((2) - 1) {}
            dash(0) = 2
            dash(1) = 2
            lineobj.SetBorderStyle(New Annot.BorderStyle(Annot.BorderStyle.Style.e_dashed, 2, 0, 0, dash))
            lineobj.RefreshAppearance()
            page.AnnotPushBack(lineobj)
            lineobj = Line.Create(doc, New Rect(347, 377, 600, 600))
            lineobj.SetStartPoint(New Point(385, 410))
            lineobj.SetEndPoint(New Point(540, 555))
            lineobj.SetStartStyle(Line.EndingStyle.e_Circle)
            lineobj.SetEndStyle(Line.EndingStyle.e_OpenArrow)
            lineobj.SetColor(New ColorPt(1, 0, 0), 3)
            lineobj.SetInteriorColor(New ColorPt(0, 1, 0), 3)
            lineobj.SetContents("Inline Caption")
            lineobj.SetShowCaption(True)
            lineobj.SetCaptionPosition(Line.CapPos.e_Inline)
            lineobj.SetLeaderLineExtensionLength(4)
            lineobj.SetLeaderLineLength(-12)
            lineobj.SetLeaderLineOffset(2)
            lineobj.RefreshAppearance()
            page.AnnotPushBack(lineobj)
            lineobj = Line.Create(doc, New Rect(10, 400, 200, 600))
            lineobj.SetStartPoint(New Point(25, 426))
            lineobj.SetEndPoint(New Point(180, 555))
            lineobj.SetStartStyle(Line.EndingStyle.e_Circle)
            lineobj.SetEndStyle(Line.EndingStyle.e_Square)
            lineobj.SetColor(New ColorPt(0, 0, 1), 3)
            lineobj.SetInteriorColor(New ColorPt(1, 0, 0), 3)
            lineobj.SetContents("Offset Caption")
            lineobj.SetShowCaption(True)
            lineobj.SetCaptionPosition(Line.CapPos.e_Top)
            lineobj.SetTextHOffset(-60)
            lineobj.SetTextVOffset(10)
            lineobj.RefreshAppearance()
            page.AnnotPushBack(lineobj)
            lineobj = Line.Create(doc, New Rect(200, 10, 400, 70))
            lineobj.SetStartPoint(New Point(220, 25))
            lineobj.SetEndPoint(New Point(370, 60))
            lineobj.SetStartStyle(Line.EndingStyle.e_Butt)
            lineobj.SetEndStyle(Line.EndingStyle.e_OpenArrow)
            lineobj.SetColor(New ColorPt(0, 0, 1), 3)
            lineobj.SetContents("Regular Caption")
            lineobj.SetShowCaption(True)
            lineobj.SetCaptionPosition(Line.CapPos.e_Top)
            lineobj.RefreshAppearance()
            page.AnnotPushBack(lineobj)
            lineobj = Line.Create(doc, New Rect(200, 70, 400, 130))
            lineobj.SetStartPoint(New Point(220, 111))
            lineobj.SetEndPoint(New Point(370, 78))
            lineobj.SetStartStyle(Line.EndingStyle.e_Circle)
            lineobj.SetEndStyle(Line.EndingStyle.e_Diamond)
            lineobj.SetContents("Circle to Diamond")
            lineobj.SetColor(New ColorPt(0, 0, 1), 3)
            lineobj.SetInteriorColor(New ColorPt(0, 1, 0), 3)
            lineobj.SetShowCaption(True)
            lineobj.SetCaptionPosition(Line.CapPos.e_Top)
            lineobj.RefreshAppearance()
            page.AnnotPushBack(lineobj)
            lineobj = Line.Create(doc, New Rect(10, 100, 160, 200))
            lineobj.SetStartPoint(New Point(15, 110))
            lineobj.SetEndPoint(New Point(150, 190))
            lineobj.SetStartStyle(Line.EndingStyle.e_Slash)
            lineobj.SetEndStyle(Line.EndingStyle.e_ClosedArrow)
            lineobj.SetContents("Slash to CArrow")
            lineobj.SetColor(New ColorPt(1, 0, 0), 3)
            lineobj.SetInteriorColor(New ColorPt(0, 1, 1), 3)
            lineobj.SetShowCaption(True)
            lineobj.SetCaptionPosition(Line.CapPos.e_Top)
            lineobj.RefreshAppearance()
            page.AnnotPushBack(lineobj)
            lineobj = Line.Create(doc, New Rect(270, 270, 570, 433))
            lineobj.SetStartPoint(New Point(300, 400))
            lineobj.SetEndPoint(New Point(550, 300))
            lineobj.SetStartStyle(Line.EndingStyle.e_RClosedArrow)
            lineobj.SetEndStyle(Line.EndingStyle.e_ROpenArrow)
            lineobj.SetContents("ROpen & RClosed arrows")
            lineobj.SetColor(New ColorPt(0, 0, 1), 3)
            lineobj.SetInteriorColor(New ColorPt(0, 1, 0), 3)
            lineobj.SetShowCaption(True)
            lineobj.SetCaptionPosition(Line.CapPos.e_Top)
            lineobj.RefreshAppearance()
            page.AnnotPushBack(lineobj)
            lineobj = Line.Create(doc, New Rect(195, 395, 205, 505))
            lineobj.SetStartPoint(New Point(200, 400))
            lineobj.SetEndPoint(New Point(200, 500))
            lineobj.RefreshAppearance()
            page.AnnotPushBack(lineobj)
            lineobj = Line.Create(doc, New Rect(55, 299, 150, 301))
            lineobj.SetStartPoint(New Point(55, 300))
            lineobj.SetEndPoint(New Point(155, 300))
            lineobj.SetStartStyle(Line.EndingStyle.e_Circle)
            lineobj.SetEndStyle(Line.EndingStyle.e_Circle)
            lineobj.SetContents("Caption that's longer than its line.")
            lineobj.SetColor(New ColorPt(1, 0, 1), 3)
            lineobj.SetInteriorColor(New ColorPt(0, 1, 0), 3)
            lineobj.SetShowCaption(True)
            lineobj.SetCaptionPosition(Line.CapPos.e_Top)
            lineobj.RefreshAppearance()
            page.AnnotPushBack(lineobj)
            lineobj = Line.Create(doc, New Rect(300, 200, 390, 234))
            lineobj.SetStartPoint(New Point(310, 210))
            lineobj.SetEndPoint(New Point(380, 220))
            lineobj.SetColor(New ColorPt(0, 0, 0), 3)
            lineobj.RefreshAppearance()
            page.AnnotPushBack(lineobj)
            Dim page3 As Page = doc.PageCreate(New Rect(0, 0, 600, 600))
            ew.Begin(page3)
            ' begin writing to the page
            ew.End()
            ' save changes to the current page
            doc.PagePushBack(page3)
            Dim circle As Circle = Circle.Create(doc, New Rect(300, 300, 390, 350))
            circle.SetColor(New ColorPt(0, 0, 0), 3)
            circle.RefreshAppearance()
            page3.AnnotPushBack(circle)
            circle = Circle.Create(doc, New Rect(100, 100, 200, 200))
            circle.SetColor(New ColorPt(0, 1, 0), 3)
            circle.SetInteriorColor(New ColorPt(0, 0, 1), 3)
            dash = New Double((2) - 1) {}
            dash(0) = 2
            dash(1) = 4
            circle.SetBorderStyle(New Annot.BorderStyle(Annot.BorderStyle.Style.e_dashed, 3, 0, 0, dash))
            circle.SetPadding(New Rect(2, 2, 2, 2))
            circle.RefreshAppearance()
            page3.AnnotPushBack(circle)
            Dim sq As Square = Square.Create(doc, New Rect(10, 200, 80, 300))
            sq.SetColor(New ColorPt(0, 0, 0), 3)
            sq.RefreshAppearance()
            page3.AnnotPushBack(sq)
            sq = Square.Create(doc, New Rect(500, 200, 580, 300))
            sq.SetColor(New ColorPt(1, 0, 0), 3)
            sq.SetInteriorColor(New ColorPt(0, 1, 1), 3)
            dash = New Double((2) - 1) {}
            dash(0) = 4
            dash(1) = 2
            sq.SetBorderStyle(New Annot.BorderStyle(Annot.BorderStyle.Style.e_dashed, 6, 0, 0, dash))
            sq.SetPadding(New Rect(4, 4, 4, 4))
            sq.RefreshAppearance()
            page3.AnnotPushBack(sq)
            Dim poly As Polygon = Polygon.Create(doc, New Rect(5, 500, 125, 590))
            poly.SetColor(New ColorPt(1, 0, 0), 3)
            poly.SetInteriorColor(New ColorPt(1, 1, 0), 3)
            poly.SetVertex(0, New Point(12, 510))
            poly.SetVertex(1, New Point(100, 510))
            poly.SetVertex(2, New Point(100, 555))
            poly.SetVertex(3, New Point(35, 544))
            poly.SetBorderStyle(New Annot.BorderStyle(Annot.BorderStyle.Style.e_solid, 4, 0, 0))
            poly.SetPadding(New Rect(4, 4, 4, 4))
            poly.RefreshAppearance()
            page3.AnnotPushBack(poly)
            Dim polyln As PolyLine = PolyLine.Create(doc, New Rect(400, 10, 500, 90))
            polyln.SetColor(New ColorPt(1, 0, 0), 3)
            polyln.SetInteriorColor(New ColorPt(0, 1, 0), 3)
            polyln.SetVertex(0, New Point(405, 20))
            polyln.SetVertex(1, New Point(440, 40))
            polyln.SetVertex(2, New Point(410, 60))
            polyln.SetVertex(3, New Point(470, 80))
            polyln.SetBorderStyle(New Annot.BorderStyle(Annot.BorderStyle.Style.e_solid, 2, 0, 0))
            polyln.SetPadding(New Rect(4, 4, 4, 4))
            polyln.SetStartStyle(Line.EndingStyle.e_RClosedArrow)
            polyln.SetEndStyle(Line.EndingStyle.e_ClosedArrow)
            polyln.RefreshAppearance()
            page3.AnnotPushBack(polyln)
            Dim lk As Link = Link.Create(doc, New Rect(5, 5, 55, 24))
            'lk.SetColor( ColorPt(0,1,0), 3 );
            lk.RefreshAppearance()
            page3.AnnotPushBack(lk)
            Dim page4 As Page = doc.PageCreate(New Rect(0, 0, 600, 600))
            ew.Begin(page4)
            ' begin writing to the page
            ew.End()
            ' save changes to the current page
            doc.PagePushBack(page4)
            ew.Begin(page4)
            Dim font As Font = Font.Create(doc, Font.StandardType1Font.e_helvetica)
            element = eb.CreateTextBegin(font, 16)
            element.SetPathFill(True)
            ew.WriteElement(element)
            element = eb.CreateTextRun("Some random text on the page", font, 16)
            element.SetTextMatrix(1, 0, 0, 1, 100, 500)
            ew.WriteElement(element)
            ew.WriteElement(eb.CreateTextEnd)
            ew.End()
            Dim hl As Highlight = Highlight.Create(doc, New Rect(100, 490, 150, 515))
            hl.SetColor(New ColorPt(0, 1, 0), 3)
            hl.RefreshAppearance()
            page4.AnnotPushBack(hl)
            Dim squig As Squiggly = Squiggly.Create(doc, New Rect(100, 450, 250, 600))
            'sq.SetColor( ColorPt(1,0,0), 3 );
            squig.SetQuadPoint(0, New QuadPoint(New Point(122, 455), New Point(240, 545), New Point(230, 595), New Point(101, 500)))
            squig.RefreshAppearance()
            page4.AnnotPushBack(squig)
            Dim cr As Caret = Caret.Create(doc, New Rect(100, 40, 129, 69))
            cr.SetColor(New ColorPt(0, 0, 1), 3)
            cr.SetSymbol("P")
            cr.RefreshAppearance()
            page4.AnnotPushBack(cr)
            Dim page5 As Page = doc.PageCreate(New Rect(0, 0, 600, 600))
            ew.Begin(page5)
            ' begin writing to the page
            ew.End()
            ' save changes to the current page
            doc.PagePushBack(page5)
            Dim page6 As Page = doc.PageCreate(New Rect(0, 0, 600, 600))
            ew.Begin(page6)
            ' begin writing to the page
            ew.End()
            ' save changes to the current page
            doc.PagePushBack(page6)
            Dim txt As Text = Text.Create(doc, New Rect(10, 20, 30, 40))
            txt.SetIcon("UserIcon")
            txt.SetContents("User defined icon, unrecognized by appearance generator")
            txt.SetColor(New ColorPt(0, 1, 0))
            txt.RefreshAppearance()
            page6.AnnotPushBack(txt)
            Dim ink As Ink = Ink.Create(doc, New Rect(100, 400, 200, 550))
            ink.SetColor(New ColorPt(0, 0, 1))
            ink.SetPoint(1, 3, New Point(220, 505))
            ink.SetPoint(1, 0, New Point(100, 490))
            ink.SetPoint(0, 1, New Point(120, 410))
            ink.SetPoint(0, 0, New Point(100, 400))
            ink.SetPoint(1, 2, New Point(180, 490))
            ink.SetPoint(1, 1, New Point(140, 440))
            ink.SetBorderStyle(New Annot.BorderStyle(Annot.BorderStyle.Style.e_solid, 3, 0, 0))
            ink.RefreshAppearance()
            page6.AnnotPushBack(ink)
            Dim page7 As Page = doc.PageCreate(New Rect(0, 0, 600, 600))
            ew.Begin(page7)
            ' begin writing to the page
            ew.End()
            ' save changes to the current page
            doc.PagePushBack(page7)
            Dim snd As Sound = Sound.Create(doc, New Rect(100, 500, 120, 520))
            snd.SetColor(New ColorPt(1, 1, 0))
            snd.SetIcon(Sound.Icon.e_Speaker)
            snd.RefreshAppearance()
            page7.AnnotPushBack(snd)
            snd = Sound.Create(doc, New Rect(200, 500, 220, 520))
            snd.SetColor(New ColorPt(1, 1, 0))
            snd.SetIcon(Sound.Icon.e_Mic)
            snd.RefreshAppearance()
            page7.AnnotPushBack(snd)
            Dim page8 As Page = doc.PageCreate(New Rect(0, 0, 600, 600))
            ew.Begin(page8)
            ' begin writing to the page
            ew.End()
            ' save changes to the current page
            doc.PagePushBack(page8)
            Dim ipage As Integer = 0
            Do While (ipage < 2)
                Dim py As Double = 520
                Dim px As Double = 5
                Dim istamp As RubberStamp.Icon = RubberStamp.Icon.e_Approved
                Do While (istamp <= RubberStamp.Icon.e_Draft)
                    Dim stmp As RubberStamp = RubberStamp.Create(doc, New Rect(1, 1, 100, 100))
                    stmp.SetIcon(istamp)
                    stmp.SetContents(stmp.GetIconName)
                    stmp.SetRect(New Rect(px, py, (px + 100), (py + 25)))
                    py = (py - 100)
                    If (py < 0) Then
                        py = 520
                        px = (px + 200)
                    End If

                    If (ipage = 0) Then

                    Else
                        page8.AnnotPushBack(stmp)
                        stmp.RefreshAppearance()
                    End If

                    istamp = CType((CType(istamp, Integer) + 1), RubberStamp.Icon)
                Loop

                ipage = (ipage + 1)
            Loop

            Dim st As RubberStamp = RubberStamp.Create(doc, New Rect(400, 5, 550, 45))
            st.SetIcon("UserStamp")
            st.SetContents("User defined stamp")
            page8.AnnotPushBack(st)
            st.RefreshAppearance()
        End Sub

        ' Relative path to the folder containing test files.
        Private Const input_path As String = "../../../../TestFiles/"

        Private Const output_path As String = "../../../../TestFiles/Output/"

        ''' <summary>
        ''' The main entry point for the application.
        ''' </summary>
        <System.STAThread()>
        Public Shared Sub Main(ByVal args() As String)
            PDFNet.Initialize(PDFTronLicense.Key)

            Try
                Dim doc As PDFDoc = New PDFDoc((input_path + "numbered.pdf"))
                doc.InitSecurityHandler()
                ' An example of using SDF/Cos API to add any type of annotations.
                Class1.AnnotationLowLevelAPI(doc)
                doc.Save((output_path + "annotation_test1.pdf"), SDFDoc.SaveOptions.e_linearized)
                System.Console.WriteLine("Done. Results saved in annotation_test1.pdf")
                ' An example of using the high-level PDFNet API to read existing annotations,
                ' to edit existing annotations, and to create new annotation from scratch.
                Class1.AnnotationHighLevelAPI(doc)
                doc.Save((output_path + "annotation_test2.pdf"), SDFDoc.SaveOptions.e_linearized)
                System.Console.WriteLine("Done. Results saved in annotation_test2.pdf")
                ' an example of creating various annotations in a brand new document
                Dim doc1 As PDFDoc = New PDFDoc
                Class1.CreateTestAnnots(doc1)
                doc1.Save((output_path + "new_annot_test_api.pdf"), SDFDoc.SaveOptions.e_linearized)
                System.Console.WriteLine("Saved new_annot_test_api.pdf")
            Catch e As PDFNetException
                System.Console.WriteLine(e.Message)
            End Try
            PDFNet.Terminate()
        End Sub
    End Class
End Namespace
```

{% endcode %}
{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/core/get-started/samples/annotationtest.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
