Some test text!

Search
Hamburger Icon

Add or edit PDF annotations in Swift

More languages

More languages
JavaScript
Java (Android)
C++
C#
C# (.NET Core)
Go
Java
Kotlin
Obj-C
JS (Node.js)
PHP
Python
Ruby
Swift
C# (UWP)
VB
C# (Xamarin)

Sample Swift code to use PDFTron 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 Swift PDF Library and PDF Annotation Library.

Get Started Samples Download

To run this sample, get started with a free trial of Apryse SDK.

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

import PDFNet
import Foundation

func AnnotationHighLevelAPI(doc: PTPDFDoc) -> Void {
    // The following code snippet traverses all annotations in the document
    print("Traversing all annotations in the document...")
    
    var page_num: Int = 1
    let itr: PTPageIterator = doc.getPageIterator(1)
    while itr.hasNext() {
        print("Page \(page_num): ")
        page_num += 1
        let page: PTPage = itr.current()
        let num_annots = page.getNumAnnots()
        for i in 0..<num_annots {
            let annot: PTAnnot = page.getAnnot(i)
            if annot.isValid() == false {
                continue
            }
            print("Annot Type: \(annot.getSDFObj().get("Subtype").value().getName()!)")
            let bbox: PTPDFRect = annot.getRect()
            print("  Position: \(bbox.getX1()), \(bbox.getY1()), \(bbox.getX2()), \(bbox.getY2())")
            switch annot.getType() {
            case e_ptLink:
                let link: PTLink = PTLink(ann: annot)
                let action: PTAction = link.getAction()
                if action.isValid() == false {
                    continue
                }
                if action.getType() == e_ptGoTo {
                    let dest: PTDestination = action.getDest()
                    if dest.isValid() == false {
                        print("  Destination is not valid\n")
                    }
                    else {
                        let page_num = dest.getPage().getIndex()
                        print("  Links to: page number \(page_num) in this document\n")
                    }
                }
                else if action.getType() == e_ptURI {
                    let uri: String = action.getSDFObj().get("URI").value().getAsPDFText()
                    print("  Links to: \(uri)\n")
                }
                
            // ...
            case e_ptWidget:
                break
            case e_ptFileAttachment:
                break
            default:
                break
            }
        }
        itr.next()
    }
    
    // Use the high-level API to create new annotations.
    let first_page: PTPage = doc.getPage(1)
    
    // Create a hyperlink...
    let hyperlink = PTLink.create(withAction: doc.getSDFDoc(), pos: PTPDFRect(x1: 85, y1: 570, x2: 503, y2: 524), action: PTAction.createURI(doc.getSDFDoc(), uri: "http://www.pdftron.com"))
    first_page.annotPushBack(hyperlink)
    
    // Create an intra-document link...
    let goto_page_3 = PTAction.createGoto(PTDestination.createFitH(doc.getPage(3), top: 0))
    let link: PTLink = PTLink.create(withAction: doc.getSDFDoc(), pos: PTPDFRect(x1: 85, y1: 458, x2: 503, y2: 502), action: goto_page_3)
    
    // Set the annotation border width to 3 points...
    let border_style = PTBorderStyle(s: e_ptsolid, b_width: 3, b_hr: 0, b_vr: 0)
    link.setBorderStyle(border_style, oldStyleOnly: false)
    link.setColor(PTColorPt(x: 0, y: 0, z: 1, w: 0), numcomp: 3)
    
    // Add the new annotation to the first page
    first_page.annotPushBack(link)
    
    // Create a stamp annotation ...
    let stamp: PTRubberStamp = PTRubberStamp.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 30, y1: 30, x2: 300, y2: 200), icon: e_ptDraft)
    stamp.setRubberStampIconName("Draft")
    first_page.annotPushBack(stamp)
    
    // Create a file attachment annotation (embed the 'peppers.jpg').
    let file_attach = PTFileAttachment.createFileAttch(withPath: doc.getSDFDoc(), pos: PTPDFRect(x1: 80, y1: 280, x2: 200, y2: 320), path: Bundle.main.path(forResource: "peppers", ofType: "jpg"), icon_name: e_ptPushPin)
    first_page.annotPushBack(file_attach)
    
    let ink: PTInk = PTInk.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 110, y1: 10, x2: 300, y2: 200))
    let pt3: PTPDFPoint = PTPDFPoint(px: 110, py: 10)
    //pt3.x = 110; pt3.y = 10;
    ink.setPoint(0, pointindex: 0, pt: pt3)
    pt3.setX(150)
    pt3.setY(50)
    ink.setPoint(0, pointindex: 1, pt: pt3)
    pt3.setX(190)
    pt3.setY(60)
    ink.setPoint(0, pointindex: 2, pt: pt3)
    pt3.setX(180)
    pt3.setY(90)
    ink.setPoint(1, pointindex: 0, pt: pt3)
    pt3.setX(190)
    pt3.setY(95)
    ink.setPoint(1, pointindex: 1, pt: pt3)
    pt3.setX(200)
    pt3.setY(100)
    ink.setPoint(1, pointindex: 2, pt: pt3)
    pt3.setX(166)
    pt3.setY(86)
    ink.setPoint(2, pointindex: 0, pt: pt3)
    pt3.setX(196)
    pt3.setY(96)
    ink.setPoint(2, pointindex: 1, pt: pt3)
    pt3.setX(221)
    pt3.setY(121)
    ink.setPoint(2, pointindex: 2, pt: pt3)
    pt3.setX(288)
    pt3.setY(188)
    ink.setPoint(2, pointindex: 3, pt: pt3)
    ink.setColor(PTColorPt(x: 0, y: 1, z: 1, w: 0), numcomp: 3)
    first_page.annotPushBack(ink)
    
    //Create a Polygon annotation..
    //    let poly: PTPolygon = PTPolygon.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 100, y1: 60, x2: 300, y2: 480))
    //    let pllp: PTPDFPoint = PTPDFPoint(px: 105, py: 68)
    //    // pllp.x = 105; pllp.y = 68;
    //    poly.setVertex(0, pt: pllp)
    //    pllp.setX(155)
    //    pllp.setY(92)
    //    poly.setVertex(1, pt: pllp)
    //    pllp.setX(189)
    //    pllp.setY(133)
    //    poly.setVertex(2, pt: pllp)
    //    pllp.setX(200)
    //    pllp.setY(140)
    //    poly.setVertex(3, pt: pllp)
    //    pllp.setX(230)
    //    pllp.setY(389)
    //    poly.setVertex(4, pt: pllp)
    //    pllp.setX(300)
    //    pllp.setY(405)
    //    poly.setVertex(5, pt: pllp)
    //    poly.setColor(PTColorPt(x: 0, y: 0, z: 1, w: 0), numcomp: 3)
    //    poly.setInteriorColor(PTColorPt(x: 1, y: 0, z: 0, w: 0), compNum: 3)
    //    first_page.annotPushBack(poly)
    
    // ...
}

func AnnotationLowLevelAPI(doc: PTPDFDoc) -> Void {
    let page: PTPage = doc.getPageIterator(1).current()
    
    let annots: PTObj
    if let optAnnots = page.getAnnots() {
        annots = optAnnots
    } else {
        // If there are no annotations, create a new annotation
        // array for the page.
        annots = doc.createIndirectArray()
        page.getSDFObj().put("Annots", obj: annots)
    }
    
    // Create a Text annotation
    let annot: PTObj = doc.createIndirectDict()
    annot.putName("Subtype", name: "Text")
    annot.putBool("Open", value: true)
    annot.put("Contents", value: "The quick brown fox ate the lazy mouse.")
    annot.putRect("Rect", x1: 266, y1: 116, x2: 430, y2: 204)
    
    // Insert the annotation in the page annotation array
    annots.pushBack(annot)
    
    // Create a Link annotation
    let link1: PTObj = doc.createIndirectDict()
    link1.putName("Subtype", name: "Link")
    let dest: PTDestination = PTDestination.createFit(doc.getPage(2))
    link1.put("Dest", obj: dest.getSDFObj())
    link1.putRect("Rect", x1: 85, y1: 705, x2: 503, y2: 661)
    annots.pushBack(link1)
    
    // Create another Link annotation
    let link2: PTObj = doc.createIndirectDict()
    link2.putName("Subtype", name: "Link")
    let dest2: PTDestination = PTDestination.createFit(doc.getPage(3))
    link2.put("Dest", obj: dest2.getSDFObj())
    link2.putRect("Rect", x1: 85, y1: 638, x2: 503, y2: 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", obj: PTDestination.createXYZ(doc.getPage(10), left: 100, top: 792 - 70, zoom: 10).getSDFObj())
    
    // Create a third link annotation with a hyperlink action (all other
    // annotation types can be created in a similar way)
    let link3: PTObj = doc.createIndirectDict()
    link3.putName("Subtype", name: "Link")
    link3.putRect("Rect", x1: 85, y1: 570, x2: 503, y2: 524)
    
    // Create a URI action
    let action: PTObj = link3.putDict("A")
    action.putName("S", name: "URI")
    action.put("URI", value: "http://www.pdftron.com")
    
    annots.pushBack(link3)
}

func CreateTestAnnots(doc: PTPDFDoc) -> Void {
    let ew: PTElementWriter = PTElementWriter()
    let eb: PTElementBuilder = PTElementBuilder()
    var element: PTElement = PTElement()
    
    let first_page: PTPage = doc.pageCreate(PTPDFRect(x1: 0, y1: 0, x2: 600, y2: 600))
    doc.pagePushBack(first_page)
    ew.writerBegin(with: first_page, placement: e_ptoverlay, page_coord_sys: false, compress: false, resources: nil)    // begin writing to this page
    ew.end()    // save changes to the current page
    
    //
    // Test of a free text annotation.
    //
    do {
        let txtannot: PTFreeText = PTFreeText.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 10, y1: 400, x2: 160, y2: 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!")
        //std::vector<double> dash( 2, 2.0 );
        txtannot.setBorderStyle(PTBorderStyle(s: e_ptsolid, b_width: 1, b_hr: 10, b_vr: 20), oldStyleOnly: true)
        txtannot.setQuaddingFormat(0)
        first_page.annotPushBack(txtannot)
        txtannot.refreshAppearance()
    }
    do {
        let txtannot: PTFreeText = PTFreeText.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 100, y1: 100, x2: 350, y2: 500))
        txtannot.setContentRect(PTPDFRect(x1: 200, y1: 200, x2: 350, y2: 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(withKneePoint: PTPDFPoint(px: 200, py: 300), p2: PTPDFPoint(px: 150, py: 290), p3: PTPDFPoint(px: 110, py: 110))
        //std::vector<double> dash( 2, 2.0 );
        txtannot.setBorderStyle(PTBorderStyle(s: e_ptsolid, b_width: 1, b_hr: 10, b_vr: 20), oldStyleOnly: true)
        txtannot.setEndingStyle(e_ptClosedArrow)
        txtannot.setColor(PTColorPt(x: 0, y: 1, z: 0, w: 0), numcomp: 3)
        txtannot.setQuaddingFormat(1)
        first_page.annotPushBack(txtannot)
        txtannot.refreshAppearance()
    }
    do {
        let txtannot: PTFreeText = PTFreeText.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 400, y1: 10, x2: 550, y2: 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(PTBorderStyle(s: e_ptsolid, b_width: 1, b_hr: 10, b_vr: 20), oldStyleOnly: true)
        txtannot.setColor(PTColorPt(x: 0, y: 0, z: 1, w: 0), numcomp: 3)
        txtannot.setOpacity(0.2)
        txtannot.setQuaddingFormat(2)
        first_page.annotPushBack(txtannot)
        txtannot.refreshAppearance()
    }
    
    let page: PTPage = doc.pageCreate(PTPDFRect(x1: 0, y1: 0, x2: 600, y2: 600))
    doc.pagePushBack(page)
    ew.writerBegin(with: page, placement: e_ptoverlay, page_coord_sys: true, compress: true, resources: nil)    // begin writing to this page
    eb.reset(PTGState())    // Reset the GState to default
    ew.end()    // save changes to the current page
    
    do {
        //Create a Line annotation...
        let line: PTLineAnnot = PTLineAnnot.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 250, y1: 250, x2: 400, y2: 400))
        line.setStart(PTPDFPoint(px: 350, py: 270))
        line.setEnd(PTPDFPoint(px: 260, py: 370))
        line.setStart(e_ptl_Square)
        line.setEnd(e_ptl_Circle)
        line.setColor(PTColorPt(x: 0.3, y: 0.5, z: 0, w: 0), numcomp: 3)
        line.setContents("Dashed Captioned")
        line.setShowCaption(true)
        line.setCaptionPosition(e_ptTop)
        let dash = NSMutableArray(capacity: 2)
        dash.add(2.0)
        dash.add(2.0)
        line.setBorderStyle(PTBorderStyle(s: e_ptdashed, b_width: 2, b_hr: 0, b_vr: 0, b_dash: dash), oldStyleOnly: false)
        line.refreshAppearance()
        page.annotPushBack(line)
    }
    do {
        let line: PTLineAnnot = PTLineAnnot.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 347, y1: 377, x2: 600, y2: 600))
        line.setStart(PTPDFPoint(px: 385, py: 410))
        line.setEnd(PTPDFPoint(px: 540, py: 555))
        line.setStart(e_ptl_Circle)
        line.setEnd(e_ptOpenArrow)
        line.setColor(PTColorPt(x: 1, y: 0, z: 0, w: 0), numcomp: 3)
        line.setContents("Inline Caption")
        line.setShowCaption(true)
        line.setCaptionPosition(e_ptInline)
        line.setLeaderLineExtensionLength(-4)
        line.setLeaderLineLength(-12)
        line.setLeaderLineOffset(2)
        line.refreshAppearance()
        page.annotPushBack(line)
    }
    
    do {
        let line: PTLineAnnot = PTLineAnnot.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 10, y1: 400, x2: 200, y2: 600))
        line.setStart(PTPDFPoint(px: 25, py: 426))
        line.setEnd(PTPDFPoint(px: 180, py: 555))
        line.setStart(e_ptl_Circle)
        line.setEnd(e_ptl_Square)
        line.setColor(PTColorPt(x: 0, y: 0, z: 1, w: 0), numcomp: 3)
        line.setInteriorColor(PTColorPt(x: 1, y: 0, z: 0, w: 0), compNum: 3)
        line.setContents("Offset Caption")
        line.setShowCaption(true)
        line.setCaptionPosition(e_ptTop)
        line.setTextHOffset(-60)
        line.setTextVOffset(10)
        line.refreshAppearance()
        page.annotPushBack(line)
    }
    do {
        let line: PTLineAnnot = PTLineAnnot.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 200, y1: 10, x2: 400, y2: 70))
        line.setStart(PTPDFPoint(px: 220, py: 25))
        line.setEnd(PTPDFPoint(px: 370, py: 60))
        line.setStart(e_ptButt)
        line.setEnd(e_ptOpenArrow)
        line.setColor(PTColorPt(x: 0, y: 0, z: 1, w: 0), numcomp: 3)
        line.setContents("Regular Caption")
        line.setShowCaption(true)
        line.setCaptionPosition(e_ptTop)
        line.refreshAppearance()
        page.annotPushBack(line)
    }
    do {
        let line: PTLineAnnot = PTLineAnnot.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 200, y1: 70, x2: 400, y2: 130))
        line.setStart(PTPDFPoint(px: 220, py: 111))
        line.setEnd(PTPDFPoint(px: 370, py: 78))
        line.setStart(e_ptl_Circle)
        line.setEnd(e_ptDiamond)
        line.setContents("Circle to Diamond")
        line.setColor(PTColorPt(x: 0, y: 0, z: 1, w: 0), numcomp: 3)
        line.setInteriorColor(PTColorPt(x: 0, y: 1, z: 0, w: 0), compNum: 3)
        line.setShowCaption(true)
        line.setCaptionPosition(e_ptTop)
        line.refreshAppearance()
        page.annotPushBack(line)
    }
    do {
        let line: PTLineAnnot = PTLineAnnot.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 10, y1: 100, x2: 160, y2: 200))
        line.setStart(PTPDFPoint(px: 15, py: 110))
        line.setEnd(PTPDFPoint(px: 150, py: 190))
        line.setStart(e_ptSlash)
        line.setEnd(e_ptClosedArrow)
        line.setContents("Slash to CArrow")
        line.setColor(PTColorPt(x: 1, y: 0, z: 0, w: 0), numcomp: 3)
        line.setInteriorColor(PTColorPt(x: 0, y: 1, z: 1, w: 0), compNum: 3)
        line.setShowCaption(true)
        line.setCaptionPosition(e_ptTop)
        line.refreshAppearance()
        page.annotPushBack(line)
    }
    do {
        let line: PTLineAnnot = PTLineAnnot.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 270, y1: 270, x2: 570, y2: 433))
        line.setStart(PTPDFPoint(px: 300, py: 400))
        line.setEnd(PTPDFPoint(px: 550, py: 300))
        line.setStart(e_ptRClosedArrow)
        line.setEnd(e_ptROpenArrow)
        line.setContents("ROpen & RClosed arrows")
        line.setColor(PTColorPt(x: 0, y: 0, z: 1, w: 0), numcomp: 3)
        line.setInteriorColor(PTColorPt(x: 0, y: 1, z: 0, w: 0), compNum: 3)
        line.setShowCaption(true)
        line.setCaptionPosition(e_ptTop)
        line.refreshAppearance()
        page.annotPushBack(line)
    }
    do {
        let line: PTLineAnnot = PTLineAnnot.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 195, y1: 395, x2: 205, y2: 505))
        line.setStart(PTPDFPoint(px: 200, py: 400))
        line.setEnd(PTPDFPoint(px: 200, py: 500))
        line.refreshAppearance()
        page.annotPushBack(line)
    }
    do {
        let line: PTLineAnnot = PTLineAnnot.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 55, y1: 299, x2: 150, y2: 301))
        line.setStart(PTPDFPoint(px: 55, py: 300))
        line.setEnd(PTPDFPoint(px: 155, py: 300))
        line.setStart(e_ptl_Circle)
        line.setEnd(e_ptl_Circle)
        line.setContents("Caption that's longer than its line")
        line.setColor(PTColorPt(x: 1, y: 0, z: 1, w: 0), numcomp: 3)
        line.setInteriorColor(PTColorPt(x: 0, y: 1, z: 0, w: 0), compNum: 3)
        line.setShowCaption(true)
        line.setCaptionPosition(e_ptTop)
        line.refreshAppearance()
        page.annotPushBack(line)
    }
    do {
        let line: PTLineAnnot = PTLineAnnot.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 300, y1: 200, x2: 290, y2: 234))
        line.setStart(PTPDFPoint(px: 310, py: 210))
        line.setEnd(PTPDFPoint(px: 380, py: 220))
        line.setColor(PTColorPt(x: 0, y: 0, z: 0, w: 0), numcomp: 3)
        line.refreshAppearance()
        page.annotPushBack(line)
    }
    
    let page3: PTPage = doc.pageCreate(PTPDFRect(x1: 0, y1: 0, x2: 600, y2: 600))
    ew.writerBegin(with: page3, placement: e_ptoverlay, page_coord_sys: true, compress: true, resources: nil)   // begin writing to the page
    ew.end()    // save changes to the current page
    doc.pagePushBack(page3)
    do {
        let circle: PTCircle = PTCircle.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 300, y1: 300, x2: 390, y2: 350))
        circle.setColor(PTColorPt(x: 0, y: 0, z: 0, w: 0), numcomp: 3)
        circle.refreshAppearance()
        page3.annotPushBack(circle)
    }
    do {
        let circle: PTCircle = PTCircle.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 100, y1: 100, x2: 200, y2: 200))
        circle.setColor(PTColorPt(x: 0, y: 1, z: 0, w: 0), numcomp: 3)
        circle.setInteriorColor(PTColorPt(x: 0, y: 0, z: 1, w: 0), compNum: 3)
        let dash = NSMutableArray(capacity: 2)
        dash.add(2.0)
        dash.add(4.0)
        circle.setBorderStyle(PTBorderStyle(s: e_ptdashed, b_width: 3, b_hr: 0, b_vr: 0, b_dash: dash), oldStyleOnly: false)
        circle.setPadding(2)
        circle.refreshAppearance()
        page3.annotPushBack(circle)
    }
    do {
        let sq: PTSquare = PTSquare.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 10, y1: 200, x2: 80, y2: 300))
        sq.setColor(PTColorPt(x: 0, y: 0, z: 0, w: 0), numcomp: 3)
        sq.refreshAppearance()
        page3.annotPushBack(sq)
    }
    do {
        let sq: PTSquare = PTSquare.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 500, y1: 200, x2: 580, y2: 300))
        sq.setColor(PTColorPt(x: 1, y: 0, z: 0, w: 0), numcomp: 3)
        sq.setInteriorColor(PTColorPt(x: 0, y: 1, z: 1, w: 0), compNum: 3)
        let dash = NSMutableArray(capacity: 2)
        dash.add(4.0)
        dash.add(2.0)
        sq.setBorderStyle(PTBorderStyle(s: e_ptdashed, b_width: 6, b_hr: 0, b_vr: 0, b_dash: dash), oldStyleOnly: false)
        sq.setPadding(4)
        sq.refreshAppearance()
        page3.annotPushBack(sq)
    }
    do {
        let poly: PTPolygon = PTPolygon.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 5, y1: 500, x2: 125, y2: 590))
        poly.setColor(PTColorPt(x: 1, y: 0, z: 0, w: 0), numcomp: 3)
        poly.setInteriorColor(PTColorPt(x: 1, y: 1, z: 0, w: 0), compNum: 3)
        poly.setVertex(0, pt: PTPDFPoint(px: 12, py: 510))
        poly.setVertex(1, pt: PTPDFPoint(px: 100, py: 510))
        poly.setVertex(2, pt: PTPDFPoint(px: 100, py: 555))
        poly.setVertex(3, pt: PTPDFPoint(px: 35, py: 544))
        poly.setBorderStyle(PTBorderStyle(s: e_ptsolid, b_width: 4, b_hr: 0, b_vr: 0), oldStyleOnly: false)
        poly.setPadding(4)
        poly.refreshAppearance()
        page3.annotPushBack(poly)
    }
    do {
        let poly: PTPolygon = PTPolygon.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 400, y1: 10, x2: 500, y2: 90))
        poly.setColor(PTColorPt(x: 1, y: 0, z: 0, w: 0), numcomp: 3)
        poly.setInteriorColor(PTColorPt(x: 0, y: 1, z: 0, w: 0), compNum: 3)
        poly.setVertex(0, pt: PTPDFPoint(px: 405, py: 20))
        poly.setVertex(1, pt: PTPDFPoint(px: 440, py: 40))
        poly.setVertex(2, pt: PTPDFPoint(px: 410, py: 60))
        poly.setVertex(3, pt: PTPDFPoint(px: 470, py: 80))
        poly.setBorderStyle(PTBorderStyle(s: e_ptsolid, b_width: 2, b_hr: 0, b_vr: 0), oldStyleOnly: false)
        poly.setPadding(4)
        poly.setStart(e_ptRClosedArrow)
        poly.setEnd(e_ptClosedArrow)
        poly.refreshAppearance()
        page3.annotPushBack(poly)
    }
    do {
        let lk: PTLink = PTLink.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 5, y1: 5, x2: 55, y2: 24))
        //lk.setColor(PTColorPt(x: 0, y: 1, z: 0, w: 0), numcomp: 3)
        lk.refreshAppearance()
        page3.annotPushBack(lk)
    }

    let page4: PTPage = doc.pageCreate(PTPDFRect(x1: 0, y1: 0, x2: 600, y2: 600))
    ew.writerBegin(with: page4, placement: e_ptoverlay, page_coord_sys: true, compress: true, resources: nil)   // begin writing to the page
    ew.end()    // save changes to the current page
    doc.pagePushBack(page4)
    
    do {
        ew.writerBegin(with: page4, placement: e_ptoverlay, page_coord_sys: true, compress: true, resources: nil)
        let font = PTFont.create(doc.getSDFDoc(), type: e_pthelvetica, embed: false)
        element = eb.createTextBegin(with: font, font_sz: 16)
        element.setPathFill(true)
        ew.write(element)
        element = eb.createTextRun(withFont: "Some random text on the page", font: font, font_sz: 16)
        element.setTextMatrix(1, b: 0, c: 0, d: 1, h: 100, v: 500)
        ew.write(element)
        ew.write(eb.createTextEnd())
        ew.end()
    }
    do {
        let hl: PTHighlightAnnot = PTHighlightAnnot.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 100, y1: 490, x2: 150, y2: 515))
        hl.setColor(PTColorPt(x: 0, y: 1, z: 0, w: 0), numcomp: 3)
        hl.refreshAppearance()
        page4.annotPushBack(hl)
    }
    do {
        let sq: PTSquiggly = PTSquiggly.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 100, y1: 450, x2: 250, y2: 600))
        //sq.setColor(PTColorPt(x: 1, y: 0, z: 0, w: 0), numcomp: 3)
        let p1 = PTPDFPoint(px: 122, py: 455)
        let p2 = PTPDFPoint(px: 240, py: 545)
        let p3 = PTPDFPoint(px: 230, py: 595)
        let p4 = PTPDFPoint(px: 101, py: 500)
        sq.setQuadPoint(0, qp: PTQuadPoint(p11: p1, p22: p2, p33: p3, p44: p4))
        sq.refreshAppearance()
        page4.annotPushBack(sq)
    }
    do {
        let cr: PTCaret = PTCaret.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 100, y1: 40, x2: 129, y2: 69))
        cr.setColor(PTColorPt(x: 0, y: 0, z: 1, w: 0), numcomp: 3)
        cr.setSymbol("P")
        cr.refreshAppearance()
        page4.annotPushBack(cr)
    }
    
    let page5: PTPage = doc.pageCreate(PTPDFRect(x1: 0, y1: 0, x2: 600, y2: 600))
    ew.writerBegin(with: page5, placement: e_ptoverlay, page_coord_sys: true, compress: true, resources: nil)   // begin writing to the page
    ew.end()    // save changes to the current page
    doc.pagePushBack(page5)
    let fs = PTFileSpec.create(doc.getSDFDoc(), path: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("butterfly.png").path, embed: false)
    let page6: PTPage = doc.pageCreate(PTPDFRect(x1: 0, y1: 0, x2: 600, y2: 600))
    ew.writerBegin(with: page6, placement: e_ptoverlay, page_coord_sys: true, compress: true, resources: nil)   // begin writing to the page
    ew.end()    // save changes to the current page
    doc.pagePushBack(page6)
    
    for ipage in 0..<2 {
        for iann in 0..<100 {
            if !(iann > e_ptTag.rawValue) {
                let fa: PTFileAttachment = PTFileAttachment.createFileAttch(withFileSpec: doc.getSDFDoc(), pos: PTPDFRect(x1: Double(50 + 50 * iann), y1: 100, x2: Double(70 + 50 * iann), y2: 120), fs: fs, icon_name: PTFileIcon.init(UInt32(iann)))
                if ipage != 0 {
                    fa.setColor(PTColorPt(x: 1, y: 1, z: 0, w: 0), numcomp: 3)
                }
                fa.refreshAppearance()
                if ipage == 0 {
                    page5.annotPushBack(fa)
                }
                else {
                    page6.annotPushBack(fa)
                }
            }
            if iann > e_ptNote.rawValue {
                break
            }
            let txt: PTText = PTText.create(doc.getSDFDoc(), pos: PTPDFRect(x1: Double(10 + iann * 50), y1: 200, x2: Double(30 + iann * 50), y2: 220))
            txt.setTextIconType(PTTextIcon.init(UInt32(iann)))
            txt.setContents(txt.getIconName())
            if ipage != 0 {
                txt.setColor(PTColorPt(x: 1, y: 1, z: 0, w: 0), numcomp: 3)
            }
            txt.refreshAppearance()
            if ipage == 0 {
                page5.annotPushBack(txt)
            }
            else {
                page6.annotPushBack(txt)
            }
        }
    }
    do {
        let txt: PTText = PTText.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 10, y1: 20, x2: 30, y2: 40))
        txt.setTextIconName("UserIcon")
        txt.setContents("User defined icon, unrecognized by appearance generator")
        txt.setColor(PTColorPt(x: 0, y: 1, z: 0, w: 0), numcomp: 3)
        txt.refreshAppearance()
        page6.annotPushBack(txt)
    }
    do {
        let ink: PTInk = PTInk.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 100, y1: 400, x2: 200, y2: 550))
        ink.setColor(PTColorPt(x: 0, y: 0, z: 1, w: 0), numcomp: 3)
        ink.setPoint(1, pointindex: 3, pt: PTPDFPoint(px: 220, py: 505))
        ink.setPoint(1, pointindex: 0, pt: PTPDFPoint(px: 100, py: 490))
        ink.setPoint(0, pointindex: 1, pt: PTPDFPoint(px: 120, py: 410))
        ink.setPoint(0, pointindex: 0, pt: PTPDFPoint(px: 100, py: 400))
        ink.setPoint(1, pointindex: 2, pt: PTPDFPoint(px: 180, py: 490))
        ink.setPoint(1, pointindex: 1, pt: PTPDFPoint(px: 140, py: 440))
        ink.setBorderStyle(PTBorderStyle(s: e_ptsolid, b_width: 3, b_hr: 0, b_vr: 0), oldStyleOnly: false)
        ink.refreshAppearance()
        page6.annotPushBack(ink)
    }
    
    let page7: PTPage = doc.pageCreate(PTPDFRect(x1: 0, y1: 0, x2: 600, y2: 600))
    ew.writerBegin(with: page7, placement: e_ptoverlay, page_coord_sys: true, compress: true, resources: nil)   // begin writing to the page
    ew.end()    // save changes to the current page
    doc.pagePushBack(page7)
    
    do {
        let snd: PTSound = PTSound.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 100, y1: 500, x2: 120, y2: 520))
        snd.setColor(PTColorPt(x: 1, y: 1, z: 0, w: 0), numcomp: 3)
        snd.setSoundIconType(e_ptSpeaker)
        snd.refreshAppearance()
        page7.annotPushBack(snd)
    }
    do {
        let snd: PTSound = PTSound.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 200, y1: 500, x2: 220, y2: 520))
        snd.setColor(PTColorPt(x: 1, y: 1, z: 0, w: 0), numcomp: 3)
        snd.setSoundIconType(e_ptMic)
        snd.refreshAppearance()
        page7.annotPushBack(snd)
    }
    
    let page8: PTPage = doc.pageCreate(PTPDFRect(x1: 0, y1: 0, x2: 600, y2: 600))
    ew.writerBegin(with: page8, placement: e_ptoverlay, page_coord_sys: true, compress: true, resources: nil)   // begin writing to the page
    ew.end()    // save changes to the current page
    doc.pagePushBack(page8)
    
    for ipage1 in 0..<2 {
        var px: Double = 5
        var py: Double = 520
        var istamp = e_ptApproved.rawValue
        while istamp <= e_ptDraft.rawValue {
            let st: PTRubberStamp = PTRubberStamp.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 1, y1: 2, x2: 200, y2: 200), icon: e_ptDraft)
            st.setRubberStampIconType(PTRubberStampIcon.init(istamp))
            st.setContents(st.getIconName())
            st.setRect(PTPDFRect(x1: px, y1: py, x2: px + 100, y2: py + 25))
            py = py - 100
            if py < 0 {
                py = 520
                px = px + 200
            }
            if ipage1 == 0 {
                //[page7 AnnotPushBack: st];
            }
            else {
                page8.annotPushBack(st)
                st.refreshAppearance()
            }
            istamp = istamp + 1
        }
    }
    let st: PTRubberStamp = PTRubberStamp.create(doc.getSDFDoc(), pos: PTPDFRect(x1: 400, y1: 5, x2: 550, y2: 45), icon: e_ptDraft)
    st.setRubberStampIconName("UserStamp")
    st.setContents("User defined stamp")
    page8.annotPushBack(st)
    st.refreshAppearance()
}

func runAnnotationTest() -> Int {
    return autoreleasepool {
        var ret: Int = 0
        
        
        do {
            try PTPDFNet.catchException {
                let doc: PTPDFDoc = PTPDFDoc(filepath: Bundle.main.path(forResource: "numbered", ofType: "pdf"))
                doc.initSecurityHandler()
                
                // An example of using SDF/Cos API to add any type of annotations.
                AnnotationLowLevelAPI(doc: doc)
                doc.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("annotation_test1.pdf").path, flags: e_ptlinearized.rawValue)
                
                // 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)
                doc.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("annotation_test2.pdf").path, flags: e_ptlinearized.rawValue)
                
                // an example of creating various annotations in a brand new document
                let doc1: PTPDFDoc = PTPDFDoc()
                CreateTestAnnots(doc: doc1)
                doc1.save(toFile: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("new_annot_test_api.pdf").path, flags: e_ptlinearized.rawValue)
                if let outputFile = doc1.getFileName(){
                    print("Saved: \(outputFile)")
                }
            }
        } catch let e as NSError {
            print("Uncaught exception: \(e)")
            ret = 1
        }
        
        return ret
    }
}