> 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/android/get-started/samples/annotationtest.md).

# Annotation

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

Sample Java code to use Apryse 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 [Android SDK](/core/get-started/languages/java.md) and [PDF Annotation Library](/core/annotation/annotation.md).

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

```java
//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2019 by PDFTron Systems Inc. All Rights Reserved.
// Consult legal.txt regarding legal and license information.
//---------------------------------------------------------------------------------------

package com.pdftron.android.pdfnetsdksamples.samples;

import com.pdftron.android.pdfnetsdksamples.OutputListener;
import com.pdftron.android.pdfnetsdksamples.PDFNetSample;
import com.pdftron.android.pdfnetsdksamples.R;
import com.pdftron.android.pdfnetsdksamples.util.Utils;
import com.pdftron.common.PDFNetException;
import com.pdftron.pdf.Action;
import com.pdftron.pdf.Annot;
import com.pdftron.pdf.Annot.BorderStyle;
import com.pdftron.pdf.ColorPt;
import com.pdftron.pdf.Destination;
import com.pdftron.pdf.Element;
import com.pdftron.pdf.ElementBuilder;
import com.pdftron.pdf.ElementWriter;
import com.pdftron.pdf.FileSpec;
import com.pdftron.pdf.Font;
import com.pdftron.pdf.PDFDoc;
import com.pdftron.pdf.Page;
import com.pdftron.pdf.PageIterator;
import com.pdftron.pdf.Point;
import com.pdftron.pdf.QuadPoint;
import com.pdftron.pdf.Rect;
import com.pdftron.pdf.annots.Caret;
import com.pdftron.pdf.annots.Circle;
import com.pdftron.pdf.annots.FreeText;
import com.pdftron.pdf.annots.Highlight;
import com.pdftron.pdf.annots.Ink;
import com.pdftron.pdf.annots.Line;
import com.pdftron.pdf.annots.Link;
import com.pdftron.pdf.annots.PolyLine;
import com.pdftron.pdf.annots.Polygon;
import com.pdftron.pdf.annots.RubberStamp;
import com.pdftron.pdf.annots.Sound;
import com.pdftron.pdf.annots.Square;
import com.pdftron.pdf.annots.Squiggly;
import com.pdftron.pdf.annots.Text;
import com.pdftron.sdf.Obj;
import com.pdftron.sdf.SDFDoc;

import java.text.DecimalFormat;
import java.util.ArrayList;

public class AnnotationTest extends PDFNetSample {

	private static OutputListener mOutputListener;

	private static ArrayList<String> mFileList = new ArrayList<>();

    public AnnotationTest() {
        setTitle(R.string.sample_annotation_title);
        setDescription(R.string.sample_annotation_description);
    }

	@Override
	public void run(OutputListener outputListener) {
		super.run(outputListener);
		mOutputListener = outputListener;
		mFileList.clear();
		printHeader(outputListener);

        try (PDFDoc doc = new PDFDoc((Utils.getAssetTempFile(INPUT_PATH + "numbered.pdf").getAbsolutePath()))) {
            doc.initSecurityHandler();

            // An example of using SDF/Cos API to add any type of annotations.
            AnnotationLowLevelAPI(doc);
            doc.save(Utils.createExternalFile("annotation_test1.pdf", mFileList).getAbsolutePath(), SDFDoc.SaveMode.LINEARIZED, null);
            mOutputListener.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(Utils.createExternalFile("annotation_test2.pdf", mFileList).getAbsolutePath(), SDFDoc.SaveMode.LINEARIZED, null);
            mOutputListener.println("Done. Results saved in annotation_test2.pdf");
        } catch (Exception e) {
            mOutputListener.printError(e.getStackTrace());
        }

        // an example of creating various annotations in a brand new document
        try (PDFDoc doc1 = new PDFDoc()) {
            CreateTestAnnots(doc1);
            doc1.save(Utils.createExternalFile("new_annot_test_api.pdf", mFileList).getAbsolutePath(), SDFDoc.SaveMode.LINEARIZED, null);
            mOutputListener.println("Saved new_annot_test_api.pdf");
        } catch (Exception e) {
            mOutputListener.printError(e.getStackTrace());
        }

		for (String file : mFileList) {
			addToFileList(file);
		}
		printFooter(outputListener);
	}

    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
        mOutputListener.println("Traversing all annotations in the document...");

        int page_num = 1;
        for (PageIterator itr = doc.getPageIterator(); itr.hasNext(); ) {
            mOutputListener.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;
                mOutputListener.println("Annot Type: " + annot.getSDFObj().get("Subtype").value().getName());

                double[] bbox = annot.getRect().get();
                mOutputListener.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) {
                                mOutputListener.println("  Destination is not valid.");
                            } else {
                                int page_link = dest.getPage().getIndex();
                                mOutputListener.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();
                            mOutputListener.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), (Utils.getAssetTempFile(INPUT_PATH + "peppers.jpg").getAbsolutePath()));
        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, Utils.getAssetTempFile(INPUT_PATH + "butterfly.png").getAbsolutePath(), 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();
    }


}
```

{% endcode %}
{% endtab %}

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

```kotlin
//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2019 by PDFTron Systems Inc. All Rights Reserved.
// Consult legal.txt regarding legal and license information.
//---------------------------------------------------------------------------------------

package com.pdftron.android.pdfnetsdksamples.samples

import com.pdftron.android.pdfnetsdksamples.OutputListener
import com.pdftron.android.pdfnetsdksamples.PDFNetSample
import com.pdftron.android.pdfnetsdksamples.R
import com.pdftron.android.pdfnetsdksamples.util.Utils
import com.pdftron.common.PDFNetException
import com.pdftron.pdf.Action
import com.pdftron.pdf.Annot
import com.pdftron.pdf.Annot.BorderStyle
import com.pdftron.pdf.ColorPt
import com.pdftron.pdf.Destination
import com.pdftron.pdf.Element
import com.pdftron.pdf.ElementBuilder
import com.pdftron.pdf.ElementWriter
import com.pdftron.pdf.FileSpec
import com.pdftron.pdf.Font
import com.pdftron.pdf.PDFDoc
import com.pdftron.pdf.Page
import com.pdftron.pdf.PageIterator
import com.pdftron.pdf.Point
import com.pdftron.pdf.QuadPoint
import com.pdftron.pdf.Rect
import com.pdftron.pdf.annots.Caret
import com.pdftron.pdf.annots.Circle
import com.pdftron.pdf.annots.FreeText
import com.pdftron.pdf.annots.Highlight
import com.pdftron.pdf.annots.Ink
import com.pdftron.pdf.annots.Line
import com.pdftron.pdf.annots.Link
import com.pdftron.pdf.annots.PolyLine
import com.pdftron.pdf.annots.Polygon
import com.pdftron.pdf.annots.RubberStamp
import com.pdftron.pdf.annots.Sound
import com.pdftron.pdf.annots.Square
import com.pdftron.pdf.annots.Squiggly
import com.pdftron.pdf.annots.Text
import com.pdftron.sdf.Obj
import com.pdftron.sdf.SDFDoc

import java.text.DecimalFormat
import java.util.ArrayList

class AnnotationTest : PDFNetSample() {
    init {
        setTitle(R.string.sample_annotation_title)
        setDescription(R.string.sample_annotation_description)
    }

    override fun run(outputListener: OutputListener?) {
        super.run(outputListener)
        mOutputListener = outputListener
        mFileList.clear()
        printHeader(outputListener!!)

        try {
            PDFDoc(Utils.getAssetTempFile(PDFNetSample.INPUT_PATH + "numbered.pdf")!!.absolutePath).use { doc ->

                doc.initSecurityHandler()

                // An example of using SDF/Cos API to add any type of annotations.
                AnnotationLowLevelAPI(doc)
                doc.save(Utils.createExternalFile("annotation_test1.pdf", mFileList).absolutePath, SDFDoc.SaveMode.LINEARIZED, null)
                mOutputListener!!.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(Utils.createExternalFile("annotation_test2.pdf", mFileList).absolutePath, SDFDoc.SaveMode.LINEARIZED, null)
                mOutputListener!!.println("Done. Results saved in annotation_test2.pdf")
            }
        } catch (e: Exception) {
            mOutputListener!!.printError(e.stackTrace)
        }

        try {
            // an example of creating various annotations in a brand new document
            PDFDoc().use { doc1 ->
                CreateTestAnnots(doc1)
                doc1.save(Utils.createExternalFile("new_annot_test_api.pdf", mFileList).absolutePath, SDFDoc.SaveMode.LINEARIZED, null)
                mOutputListener!!.println("Saved new_annot_test_api.pdf")
            }
        } catch (e: Exception) {
            mOutputListener!!.printError(e.stackTrace)
        }

        for (file in mFileList) {
            addToFileList(file)
        }
        printFooter(outputListener)
    }

    companion object {

        private var mOutputListener: OutputListener? = null

        private val mFileList = ArrayList<String>()

        val format = DecimalFormat("0.#")

        @Throws(PDFNetException::class)
        internal fun AnnotationHighLevelAPI(doc: PDFDoc) {
            // The following code snippet traverses all annotations in the document
            mOutputListener!!.println("Traversing all annotations in the document...")

            var page_num = 1
            val itr = doc.pageIterator
            while (itr.hasNext()) {
                mOutputListener!!.println("Page " + page_num++ + ": ")

                val page = itr.next()
                val num_annots = page!!.getNumAnnots()
                loop@ for (i in 0 until num_annots) {
                    val annot = page.getAnnot(i)
                    if (annot.isValid == false) continue
                    mOutputListener!!.println("Annot Type: " + annot.sdfObj.get("Subtype").value().name)

                    val bbox = annot.rect.get()
                    mOutputListener!!.println("  Position: " + format.format(bbox[0])
                            + ", " + format.format(bbox[1])
                            + ", " + format.format(bbox[2])
                            + ", " + format.format(bbox[3]))

                    when (annot.type) {
                        Annot.e_Link -> {
                            val link = com.pdftron.pdf.annots.Link(annot)
                            val action = link.action
                            if (action.isValid == false) continue@loop
                            if (action.type == Action.e_GoTo) {
                                val dest = action.dest
                                if (dest.isValid == false) {
                                    mOutputListener!!.println("  Destination is not valid.")
                                } else {
                                    val page_link = dest.page.index
                                    mOutputListener!!.println("  Links to: page number $page_link in this document")
                                }
                            } else if (action.type == Action.e_URI) {
                                val uri = action.sdfObj.get("URI").value().asPDFText
                                mOutputListener!!.println("  Links to: $uri")
                            }
                            // ...
                        }
                        Annot.e_Widget -> {
                        }
                        Annot.e_FileAttachment -> {
                        }
                        // ...
                        else -> {
                        }
                    }
                }
            }

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

            // Create a hyperlink...
            val hyperlink = com.pdftron.pdf.annots.Link.create(doc, Rect(85.0, 570.0, 503.0, 524.0), Action.createURI(doc, "http://www.pdftron.com"))
            first_page.annotPushBack(hyperlink)

            // Create an intra-document link...
            val goto_page_3 = Action.createGoto(Destination.createFitH(doc.getPage(3), 0.0))
            val link = com.pdftron.pdf.annots.Link.create(doc.sdfDoc,
                    Rect(85.0, 458.0, 503.0, 502.0),
                    goto_page_3)
            link.setColor(ColorPt(1.0, 0.0, 0.0), 3)

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

            // Create a stamp annotation ...
            val stamp = com.pdftron.pdf.annots.RubberStamp.create(doc, 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').
            val file_attach = com.pdftron.pdf.annots.FileAttachment.create(doc, Rect(80.0, 280.0, 108.0, 320.0), Utils.getAssetTempFile(PDFNetSample.INPUT_PATH + "peppers.jpg")!!.absolutePath)
            first_page.annotPushBack(file_attach)

            val ink = com.pdftron.pdf.annots.Ink.create(doc, Rect(110.0, 10.0, 300.0, 200.0))
            val pt3 = Point(110.0, 10.0)
            //pt3.x = 110; pt3.y = 10;
            ink.setPoint(0, 0, pt3)
            pt3.x = 150.0
            pt3.y = 50.0
            ink.setPoint(0, 1, pt3)
            pt3.x = 190.0
            pt3.y = 60.0
            ink.setPoint(0, 2, pt3)
            pt3.x = 180.0
            pt3.y = 90.0
            ink.setPoint(1, 0, pt3)
            pt3.x = 190.0
            pt3.y = 95.0
            ink.setPoint(1, 1, pt3)
            pt3.x = 200.0
            pt3.y = 100.0
            ink.setPoint(1, 2, pt3)
            pt3.x = 166.0
            pt3.y = 86.0
            ink.setPoint(2, 0, pt3)
            pt3.x = 196.0
            pt3.y = 96.0
            ink.setPoint(2, 1, pt3)
            pt3.x = 221.0
            pt3.y = 121.0
            ink.setPoint(2, 2, pt3)
            pt3.x = 288.0
            pt3.y = 188.0
            ink.setPoint(2, 3, pt3)
            ink.setColor(ColorPt(0.0, 1.0, 1.0), 3)
            first_page.annotPushBack(ink)

        }

        @Throws(PDFNetException::class)
        internal fun AnnotationLowLevelAPI(doc: PDFDoc) {
            val page = doc.pageIterator.next()

            var annots: Obj? = 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
            val 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
            val link1 = doc.createIndirectDict()
            link1.putName("Subtype", "Link")
            val dest = Destination.createFit(doc.getPage(2))
            link1.put("Dest", dest.sdfObj)
            link1.putRect("Rect", 85.0, 705.0, 503.0, 661.0)
            annots.pushBack(link1)

            // Create another Link annotation
            val link2 = doc.createIndirectDict()
            link2.putName("Subtype", "Link")
            val dest2 = Destination.createFit(doc.getPage(3))
            link2.put("Dest", dest2.sdfObj)
            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",
                    Destination.createXYZ(doc.getPage(10), 100.0, (792 - 70).toDouble(), 10.0).sdfObj)

            // Create a third link annotation with a hyperlink action (all other
            // annotation types can be created in a similar way)
            val link3 = doc.createIndirectDict()
            link3.putName("Subtype", "Link")
            link3.putRect("Rect", 85.0, 570.0, 503.0, 524.0)

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

            annots.pushBack(link3)
        }

        @Throws(PDFNetException::class)
        internal fun CreateTestAnnots(doc: PDFDoc) {
            val ew = ElementWriter()
            val eb = ElementBuilder()
            var element: Element

            val first_page = doc.pageCreate(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.
            //
            run {
                val txtannot = FreeText.create(doc, Rect(10.0, 400.0, 160.0, 570.0))
                txtannot.contents = "\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.borderStyle = Annot.BorderStyle(Annot.BorderStyle.e_solid, 1, 10, 20)
                txtannot.quaddingFormat = 0
                first_page.annotPushBack(txtannot)
                txtannot.refreshAppearance()
            }
            run {
                val txtannot = FreeText.create(doc, Rect(100.0, 100.0, 350.0, 500.0))
                txtannot.contentRect = Rect(200.0, 200.0, 350.0, 500.0)
                txtannot.contents = "\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.0, 300.0), Point(150.0, 290.0), Point(110.0, 110.0))
                txtannot.borderStyle = Annot.BorderStyle(Annot.BorderStyle.e_solid, 1, 10, 20)
                txtannot.endingStyle = Line.e_ClosedArrow
                txtannot.setColor(ColorPt(0.0, 1.0, 0.0))
                txtannot.quaddingFormat = 1
                first_page.annotPushBack(txtannot)
                txtannot.refreshAppearance()
            }
            run {
                val txtannot = FreeText.create(doc, Rect(400.0, 10.0, 550.0, 400.0))
                txtannot.contents = "\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.borderStyle = Annot.BorderStyle(Annot.BorderStyle.e_solid, 1, 10, 20)
                txtannot.setColor(ColorPt(0.0, 0.0, 1.0))
                txtannot.opacity = 0.2
                txtannot.quaddingFormat = 2
                first_page.annotPushBack(txtannot)
                txtannot.refreshAppearance()
            }

            val page = doc.pageCreate(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

            run {
                //Create a Line annotation...
                val line = Line.create(doc, Rect(250.0, 250.0, 400.0, 400.0))
                line.startPoint = Point(350.0, 270.0)
                line.endPoint = Point(260.0, 370.0)
                line.startStyle = Line.e_Square
                line.endStyle = Line.e_Circle
                line.setColor(ColorPt(.3, .5, 0.0), 3)
                line.contents = "Dashed Captioned"
                line.showCaption = true
                line.captionPosition = Line.e_Top
                val dash = doubleArrayOf(2.0, 2.0)
                line.borderStyle = Annot.BorderStyle(Annot.BorderStyle.e_dashed, 2, 0, 0, dash)
                line.refreshAppearance()
                page.annotPushBack(line)
            }
            run {
                val line = Line.create(doc, Rect(347.0, 377.0, 600.0, 600.0))
                line.startPoint = Point(385.0, 410.0)
                line.endPoint = Point(540.0, 555.0)
                line.startStyle = Line.e_Circle
                line.endStyle = Line.e_OpenArrow
                line.setColor(ColorPt(1.0, 0.0, 0.0), 3)
                line.setInteriorColor(ColorPt(0.0, 1.0, 0.0), 3)
                line.contents = "Inline Caption"
                line.showCaption = true
                line.captionPosition = Line.e_Inline
                line.leaderLineExtensionLength = 4.0
                line.leaderLineLength = -12.0
                line.leaderLineOffset = 2.0
                line.refreshAppearance()
                page.annotPushBack(line)
            }
            run {
                val line = Line.create(doc, Rect(10.0, 400.0, 200.0, 600.0))
                line.startPoint = Point(25.0, 426.0)
                line.endPoint = Point(180.0, 555.0)
                line.startStyle = Line.e_Circle
                line.endStyle = Line.e_Square
                line.setColor(ColorPt(0.0, 0.0, 1.0), 3)
                line.setInteriorColor(ColorPt(1.0, 0.0, 0.0), 3)
                line.contents = "Offset Caption"
                line.showCaption = true
                line.captionPosition = Line.e_Top
                line.textHOffset = -60.0
                line.textVOffset = 10.0
                line.refreshAppearance()
                page.annotPushBack(line)
            }
            run {
                val line = Line.create(doc, Rect(200.0, 10.0, 400.0, 70.0))
                line.startPoint = Point(220.0, 25.0)
                line.endPoint = Point(370.0, 60.0)
                line.startStyle = Line.e_Butt
                line.endStyle = Line.e_OpenArrow
                line.setColor(ColorPt(0.0, 0.0, 1.0), 3)
                line.contents = "Regular Caption"
                line.showCaption = true
                line.captionPosition = Line.e_Top
                line.refreshAppearance()
                page.annotPushBack(line)
            }
            run {
                val line = Line.create(doc, Rect(200.0, 70.0, 400.0, 130.0))
                line.startPoint = Point(220.0, 111.0)
                line.endPoint = Point(370.0, 78.0)
                line.startStyle = Line.e_Circle
                line.endStyle = Line.e_Diamond
                line.contents = "Circle to Diamond"
                line.setColor(ColorPt(0.0, 0.0, 1.0), 3)
                line.setInteriorColor(ColorPt(0.0, 1.0, 0.0), 3)
                line.showCaption = true
                line.captionPosition = Line.e_Top
                line.refreshAppearance()
                page.annotPushBack(line)
            }
            run {
                val line = Line.create(doc, Rect(10.0, 100.0, 160.0, 200.0))
                line.startPoint = Point(15.0, 110.0)
                line.endPoint = Point(150.0, 190.0)
                line.startStyle = Line.e_Slash
                line.endStyle = Line.e_ClosedArrow
                line.contents = "Slash to CArrow"
                line.setColor(ColorPt(1.0, 0.0, 0.0), 3)
                line.setInteriorColor(ColorPt(0.0, 1.0, 1.0), 3)
                line.showCaption = true
                line.captionPosition = Line.e_Top
                line.refreshAppearance()
                page.annotPushBack(line)
            }
            run {
                val line = Line.create(doc, Rect(270.0, 270.0, 570.0, 433.0))
                line.startPoint = Point(300.0, 400.0)
                line.endPoint = Point(550.0, 300.0)
                line.startStyle = Line.e_RClosedArrow
                line.endStyle = Line.e_ROpenArrow
                line.contents = "ROpen & RClosed arrows"
                line.setColor(ColorPt(0.0, 0.0, 1.0), 3)
                line.setInteriorColor(ColorPt(0.0, 1.0, 0.0), 3)
                line.showCaption = true
                line.captionPosition = Line.e_Top
                line.refreshAppearance()
                page.annotPushBack(line)
            }
            run {
                val line = Line.create(doc, Rect(195.0, 395.0, 205.0, 505.0))
                line.startPoint = Point(200.0, 400.0)
                line.endPoint = Point(200.0, 500.0)
                line.refreshAppearance()
                page.annotPushBack(line)
            }
            run {
                val line = Line.create(doc, Rect(55.0, 299.0, 150.0, 301.0))
                line.startPoint = Point(55.0, 300.0)
                line.endPoint = Point(155.0, 300.0)
                line.startStyle = Line.e_Circle
                line.endStyle = Line.e_Circle
                line.contents = "Caption that's longer than its line."
                line.setColor(ColorPt(1.0, 0.0, 1.0), 3)
                line.setInteriorColor(ColorPt(0.0, 1.0, 0.0), 3)
                line.showCaption = true
                line.captionPosition = Line.e_Top
                line.refreshAppearance()
                page.annotPushBack(line)
            }
            run {
                val line = Line.create(doc, Rect(300.0, 200.0, 390.0, 234.0))
                line.startPoint = Point(310.0, 210.0)
                line.endPoint = Point(380.0, 220.0)
                line.setColor(ColorPt(0.0, 0.0, 0.0), 3)
                line.refreshAppearance()
                page.annotPushBack(line)
            }

            val page3 = doc.pageCreate(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)
            run {
                val circle = Circle.create(doc, Rect(300.0, 300.0, 390.0, 350.0))
                circle.setColor(ColorPt(0.0, 0.0, 0.0), 3)
                circle.refreshAppearance()
                page3.annotPushBack(circle)
            }
            run {
                val circle = Circle.create(doc, Rect(100.0, 100.0, 200.0, 200.0))
                circle.setColor(ColorPt(0.0, 1.0, 0.0), 3)
                circle.setInteriorColor(ColorPt(0.0, 0.0, 1.0), 3)
                val dash = doubleArrayOf(2.0, 4.0)
                circle.borderStyle = Annot.BorderStyle(Annot.BorderStyle.e_dashed, 3, 0, 0, dash)
                circle.setPadding(2.0)
                circle.refreshAppearance()
                page3.annotPushBack(circle)
            }
            run {
                val sq = Square.create(doc, Rect(10.0, 200.0, 80.0, 300.0))
                sq.setColor(ColorPt(0.0, 0.0, 0.0), 3)
                sq.refreshAppearance()
                page3.annotPushBack(sq)
            }
            run {
                val sq = Square.create(doc, Rect(500.0, 200.0, 580.0, 300.0))
                sq.setColor(ColorPt(1.0, 0.0, 0.0), 3)
                sq.setInteriorColor(ColorPt(0.0, 1.0, 1.0), 3)
                val dash = doubleArrayOf(4.0, 2.0)
                sq.borderStyle = Annot.BorderStyle(Annot.BorderStyle.e_dashed, 6, 0, 0, dash)
                sq.setPadding(4.0)
                sq.refreshAppearance()
                page3.annotPushBack(sq)
            }
            run {
                val poly = Polygon.create(doc, Rect(5.0, 500.0, 125.0, 590.0))
                poly.setColor(ColorPt(1.0, 0.0, 0.0), 3)
                poly.setInteriorColor(ColorPt(1.0, 1.0, 0.0), 3)
                poly.setVertex(0, Point(12.0, 510.0))
                poly.setVertex(1, Point(100.0, 510.0))
                poly.setVertex(2, Point(100.0, 555.0))
                poly.setVertex(3, Point(35.0, 544.0))
                poly.borderStyle = Annot.BorderStyle(Annot.BorderStyle.e_solid, 4, 0, 0)
                poly.setPadding(4.0)
                poly.refreshAppearance()
                page3.annotPushBack(poly)
            }
            run {
                val poly = PolyLine.create(doc, Rect(400.0, 10.0, 500.0, 90.0))
                poly.setColor(ColorPt(1.0, 0.0, 0.0), 3)
                poly.setInteriorColor(ColorPt(0.0, 1.0, 0.0), 3)
                poly.setVertex(0, Point(405.0, 20.0))
                poly.setVertex(1, Point(440.0, 40.0))
                poly.setVertex(2, Point(410.0, 60.0))
                poly.setVertex(3, Point(470.0, 80.0))
                poly.borderStyle = Annot.BorderStyle(Annot.BorderStyle.e_solid, 2, 0, 0)
                poly.setPadding(4.0)
                poly.startStyle = Line.e_RClosedArrow
                poly.endStyle = Line.e_ClosedArrow
                poly.refreshAppearance()
                page3.annotPushBack(poly)
            }
            run {
                val lk = Link.create(doc, Rect(5.0, 5.0, 55.0, 24.0))
                lk.refreshAppearance()
                page3.annotPushBack(lk)
            }

            val page4 = doc.pageCreate(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)

            run {
                ew.begin(page4)
                val font = Font.create(doc, 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()
            }
            run {
                val hl = Highlight.create(doc, Rect(100.0, 490.0, 150.0, 515.0))
                hl.setColor(ColorPt(0.0, 1.0, 0.0), 3)
                hl.refreshAppearance()
                page4.annotPushBack(hl)
            }
            run {
                val sq = Squiggly.create(doc, Rect(100.0, 450.0, 250.0, 600.0))
                sq.setQuadPoint(0, QuadPoint(Point(122.0, 455.0), Point(240.0, 545.0), Point(230.0, 595.0), Point(101.0, 500.0)))
                sq.refreshAppearance()
                page4.annotPushBack(sq)
            }
            run {
                val cr = Caret.create(doc, Rect(100.0, 40.0, 129.0, 69.0))
                cr.setColor(ColorPt(0.0, 0.0, 1.0), 3)
                cr.symbol = "P"
                cr.refreshAppearance()
                page4.annotPushBack(cr)
            }

            val page5 = doc.pageCreate(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)
            val fs = FileSpec.create(doc, Utils.getAssetTempFile(PDFNetSample.INPUT_PATH + "butterfly.png")!!.absolutePath, false)
            val page6 = doc.pageCreate(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)

            run {
                val txt = Text.create(doc, Point(10.0, 20.0))
                txt.setIcon("UserIcon")
                txt.contents = "User defined icon, unrecognized by appearance generator"
                txt.setColor(ColorPt(0.0, 1.0, 0.0))
                txt.refreshAppearance()
                page6.annotPushBack(txt)
            }
            run {
                val ink = Ink.create(doc, Rect(100.0, 400.0, 200.0, 550.0))
                ink.setColor(ColorPt(0.0, 0.0, 1.0))
                ink.setPoint(1, 3, Point(220.0, 505.0))
                ink.setPoint(1, 0, Point(100.0, 490.0))
                ink.setPoint(0, 1, Point(120.0, 410.0))
                ink.setPoint(0, 0, Point(100.0, 400.0))
                ink.setPoint(1, 2, Point(180.0, 490.0))
                ink.setPoint(1, 1, Point(140.0, 440.0))
                ink.borderStyle = Annot.BorderStyle(Annot.BorderStyle.e_solid, 3, 0, 0)
                ink.refreshAppearance()
                page6.annotPushBack(ink)
            }

            val page7 = doc.pageCreate(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)

            run {
                val snd = Sound.create(doc, Rect(100.0, 500.0, 120.0, 520.0))
                snd.setColor(ColorPt(1.0, 1.0, 0.0))
                snd.icon = Sound.e_Speaker
                snd.refreshAppearance()
                page7.annotPushBack(snd)
            }
            run {
                val snd = Sound.create(doc, Rect(200.0, 500.0, 220.0, 520.0))
                snd.setColor(ColorPt(1.0, 1.0, 0.0))
                snd.icon = Sound.e_Mic
                snd.refreshAppearance()
                page7.annotPushBack(snd)
            }

            val page8 = doc.pageCreate(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 in 0..1) {
                var px = 5.0
                var py = 520.0
                for (istamp in 0..RubberStamp.e_Draft) {
                    val st = RubberStamp.create(doc, Rect(1.0, 1.0, 100.0, 100.0))
                    st.SetIcon(istamp)
                    st.contents = st.iconName
                    st.rect = Rect(px, py, px + 100, py + 25)
                    py -= 100.0
                    if (py < 0) {
                        py = 520.0
                        px += 200.0
                    }
                    if (ipage == 0)
                    else {
                        page8.annotPushBack(st)
                        st.refreshAppearance()
                    }//page7.AnnotPushBack( st );
                }
            }
            val st = RubberStamp.create(doc, Rect(400.0, 5.0, 550.0, 45.0))
            st.setIcon("UserStamp")
            st.contents = "User defined stamp"
            page8.annotPushBack(st)
            st.refreshAppearance()
        }
    }

}
```

{% 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/android/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.
