Some test text!

menu
search

Add or edit PDF annotations in Swift

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 PDF Annotation Library.

Get StartedSamplesDownload

To run this sample, get started with a free trial of PDFTron 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)
                print("\("Saved ../../TestFiles/Output/new_annot_test_api.pdf")")
            }
        } catch let e as NSError {
            print("Uncaught exception: \(e)")
            ret = 1
        }
        
        return ret
    }
}
close

Free Trial

Get unlimited trial usage of PDFTron SDK to bring accurate, reliable, and fast document processing capabilities to any application or workflow.

Select a platform to get started with your free trial.

Unlimited usage. No email address required.

PDFTron Receives USD$71 Million Growth Investment Led By Silversmith Capital Partners

Learn More
close