Skip to content
DemoSampleAPI ReferenceFAQ

PDF Generation Template Editor

Open-source visual PDF generation engine with customizable templates and developer-friendly APIs.

View on GitHub

Add Annotations to PDF ​

This sample shows how to print the annotation list information, set the annotations (including markup, note, ink, freetext, circle, square, line, stamp, and sound annotations), and delete the annotations

Java
/**
 * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
 * <p>
 * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
 * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDF LICENSE AGREEMENT.
 * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
 * This notice may not be removed from this file.
 */

package com.compdfkit.samples.samples;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.PointF;
import android.graphics.RectF;

import com.compdfkit.core.annotation.CPDFAnnotation;
import com.compdfkit.core.annotation.CPDFBorderStyle;
import com.compdfkit.core.annotation.CPDFCircleAnnotation;
import com.compdfkit.core.annotation.CPDFFreetextAnnotation;
import com.compdfkit.core.annotation.CPDFHighlightAnnotation;
import com.compdfkit.core.annotation.CPDFInkAnnotation;
import com.compdfkit.core.annotation.CPDFLineAnnotation;
import com.compdfkit.core.annotation.CPDFLinkAnnotation;
import com.compdfkit.core.annotation.CPDFSoundAnnotation;
import com.compdfkit.core.annotation.CPDFSquareAnnotation;
import com.compdfkit.core.annotation.CPDFStampAnnotation;
import com.compdfkit.core.annotation.CPDFTextAnnotation;
import com.compdfkit.core.annotation.CPDFTextAttribute;
import com.compdfkit.core.document.CPDFDestination;
import com.compdfkit.core.document.CPDFDocument;
import com.compdfkit.core.document.action.CPDFGoToAction;
import com.compdfkit.core.page.CPDFPage;
import com.compdfkit.samples.PDFSamples;
import com.compdfkit.samples.R;
import com.compdfkit.samples.SampleApplication;
import com.compdfkit.samples.util.FileUtils;
import com.compdfkit.samples.util.OutputListener;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


public class AnnotationTest extends PDFSamples {

    public AnnotationTest() {
        setTitle(R.string.annotation_test_title);
        setDescription(R.string.annotation_test_desc);
    }

    @Override
    protected void run(OutputListener outputListener) {
        super.run(outputListener);
        printHead();

        CPDFDocument document = new CPDFDocument(context);
        document.open(FileUtils.getAssetsTempFile(context, "CommonFivePage.pdf"));

        printDividingLine();
        //------------------------------------------
        //Samples 1 : add freetext annotation
        addFreeText(document);

        //------------------------------------------
        //Samples 2 : add ink annotation
        addInk(document);

        //------------------------------------------
        //Samples 3 : add line annotation
        addLine(document);

        //------------------------------------------
        //Samples 4 : add circle annotation
        addCircleShape(document);

        //------------------------------------------
        //Samples 5 : add square annotation
        addSquareShape(document);

        //------------------------------------------
        //Samples 6 : add highlight(markup) annotation
        addHighlight(document);

        //------------------------------------------
        //Samples 7 : add link annotation
        addLink(document);

        //------------------------------------------
        //Samples 8 : add note annotation
        addNote(document);

        //------------------------------------------
        //Samples 8 : add sound annotation
        addSound(document);

        //------------------------------------------
        //Samples 9 : add stamp annotation
        addStamp(document);

        File file = new File(outputDir(), "AnnotationTest/CreateAnnotationTest.pdf");
        saveSamplePDF(document, file, true);
        outputListener.println("Done.");
        outputListener.println("\nDone. Result saved in CreateAnnotationTest.pdf");
        printDividingLine();

        //------------------------------------------
        //Samples 10 : print annotation list info
        printAnnotationList();

        //------------------------------------------
        //Samples 11 : delete annotation
        deleteAnnotation();

        printFooter();
    }

    /**
     * Samples 1 : add freetext annotation
     *
     * @param document
     */
    private void addFreeText(CPDFDocument document) {
        // Insert the free text annotation into the first page of the PDF document.
        CPDFPage page1 = document.pageAtIndex(0);
        CPDFFreetextAnnotation freetextAnnotation = (CPDFFreetextAnnotation) page1.addAnnot(CPDFAnnotation.Type.FREETEXT);
        RectF freeText1Rect = getConvertRect(page1, new RectF(10, 200, 160, 570));
        freetextAnnotation.setRect(freeText1Rect);
        // set text alignment
        freetextAnnotation.setFreetextAlignment(CPDFFreetextAnnotation.Alignment.ALIGNMENT_LEFT);
        // Set text font, bold, italic, color and font size
        CPDFTextAttribute textAttribute = new CPDFTextAttribute(CPDFTextAttribute.FontNameHelper.obtainFontName(
                CPDFTextAttribute.FontNameHelper.FontType.Courier, false, false
        ), 12, Color.RED);
        freetextAnnotation.setFreetextDa(textAttribute);
        // set text color opacity
        freetextAnnotation.setAlpha(255);
        freetextAnnotation.setContent("Some swift brown fox snatched a gray hare out of the air by freezing it with an angry glare.\n" +
                "\n" +
                "Aha!\n" +
                "\n" +
                "And there was much rejoicing!");
        freetextAnnotation.updateAp();
    }

    /**
     * Samples 2 : add ink annotation
     *
     * @param document
     */
    private void addInk(CPDFDocument document) {
        // Insert the ink annotation into the first page of the PDF document.
        CPDFPage page1 = document.pageAtIndex(0);
        ArrayList<ArrayList<PointF>> mDrawing = new ArrayList<>();
        ArrayList<PointF> arc1 = new ArrayList<>();
        arc1.add(new PointF(100, 100));
        arc1.add(new PointF(110, 110));
        arc1.add(new PointF(120, 120));
        mDrawing.add(arc1);
        ArrayList<PointF> arc2 = new ArrayList<>();
        arc2.add(new PointF(115, 115));
        arc2.add(new PointF(130, 130));
        arc2.add(new PointF(160, 160));
        mDrawing.add(arc2);
        float scaleValue = 1F;
        float borderWidth = 5F;
        CPDFInkAnnotation inkAnnotation = (CPDFInkAnnotation) page1.addAnnot(CPDFInkAnnotation.Type.INK);
        inkAnnotation.setColor(Color.RED);
        inkAnnotation.setAlpha(255);
        inkAnnotation.setBorderWidth(borderWidth);
        RectF rect = null;
        RectF size = document.getPageSize(0);
        if (size.isEmpty()) {
            return;
        }
        int lineCount = mDrawing.size();
        PointF[][] path = new PointF[lineCount][];
        for (int lineIndex = 0; lineIndex < lineCount; lineIndex++) {
            ArrayList<PointF> line = mDrawing.get(lineIndex);
            int pointCount = line.size();
            PointF[] linePath = new PointF[pointCount];
            for (int pointIndex = 0; pointIndex < pointCount; pointIndex++) {
                PointF point = line.get(pointIndex);
                // Calculate the smallest Rect that the Path is surrounded by
                if (rect == null) {
                    rect = new RectF(point.x, point.y, point.x, point.y);
                } else {
                    rect.union(point.x, point.y);
                }
                // Calculate the coordinate points that are converted to the Page and stored in the linePath collection
                linePath[pointIndex] = (page1.convertPointToPage(false, size.width(), size.height(), point));
            }
            path[lineIndex] = linePath;
        }
        float dx = borderWidth / scaleValue / 2;
        rect.inset(-dx, -dx);
        rect.set(page1.convertRectToPage(false, size.width(), size.height(), rect));
        inkAnnotation.setInkPath(path);
        inkAnnotation.setRect(rect);
        inkAnnotation.updateAp();
        mDrawing.clear();
    }

    /**
     * Samples 3 : add line shape annotation
     *
     * @param document
     */
    private void addLine(CPDFDocument document) {
        // Add a green dotted line annotation
        CPDFPage page2 = document.pageAtIndex(1);
        CPDFLineAnnotation lineAnnotation = (CPDFLineAnnotation) page2.addAnnot(CPDFAnnotation.Type.LINE);
        // line start point
        PointF startPoint = new PointF(200, 100);
        // line end point
        PointF endPoint = new PointF(50, 300);
        RectF area = new RectF();
        // Get the position of the line on the page
        convertLinePoint(page2, startPoint, endPoint, area);
        lineAnnotation.setRect(area);
        lineAnnotation.setLinePoints(startPoint, endPoint);
        // Sets the arrowhead shape at both ends of the line
        lineAnnotation.setLineType(CPDFLineAnnotation.LineType.LINETYPE_NONE, CPDFLineAnnotation.LineType.LINETYPE_NONE);
        // Set line to dash and spacer width
        CPDFBorderStyle borderStyle = new CPDFBorderStyle(CPDFBorderStyle.Style.Border_Dashed, 10, new float[]{8, 4F});
        lineAnnotation.setBorderStyle(borderStyle);
        // set line width
        lineAnnotation.setBorderWidth(3);
        lineAnnotation.setBorderAlpha(255);
        lineAnnotation.setBorderColor(Color.GREEN);
        lineAnnotation.updateAp();

        //Add a solid red line annotation with an arrow type
        CPDFLineAnnotation lineAnnotation2 = (CPDFLineAnnotation) page2.addAnnot(CPDFAnnotation.Type.LINE);
        PointF startPoint2 = new PointF(200, 350);
        PointF endPoint2 = new PointF(50, 550);
        RectF area2 = new RectF();
        convertLinePoint(page2, startPoint2, endPoint2, area2);
        lineAnnotation2.setRect(area2);
        lineAnnotation2.setLinePoints(startPoint2, endPoint2);
        // Set the start position of the arrow as circle and the end of the arrow as the arrow type
        lineAnnotation2.setLineType(CPDFLineAnnotation.LineType.LINETYPE_CIRCLE, CPDFLineAnnotation.LineType.LINETYPE_ARROW);
        // set line to solid
        CPDFBorderStyle borderStyle2 = new CPDFBorderStyle(CPDFBorderStyle.Style.Border_Solid, 10, new float[]{8, 0});
        lineAnnotation2.setBorderStyle(borderStyle2);
        lineAnnotation2.setBorderWidth(5);
        lineAnnotation2.setBorderAlpha(255);
        lineAnnotation2.setBorderColor(Color.RED);
        lineAnnotation2.updateAp();

        // Add a solid red line annotation
        CPDFLineAnnotation lineAnnotation3 = (CPDFLineAnnotation) page2.addAnnot(CPDFAnnotation.Type.LINE);
        PointF startPoint3 = new PointF(400, 100);
        PointF endPoint3 = new PointF(250, 300);
        RectF area3 = new RectF();
        convertLinePoint(page2, startPoint3, endPoint3, area3);
        lineAnnotation3.setRect(area3);
        lineAnnotation3.setLinePoints(startPoint3, endPoint3);
        lineAnnotation3.setLineType(CPDFLineAnnotation.LineType.LINETYPE_NONE, CPDFLineAnnotation.LineType.LINETYPE_NONE);
        CPDFBorderStyle borderStyle3 = new CPDFBorderStyle(CPDFBorderStyle.Style.Border_Solid, 10, new float[]{8, 0});
        lineAnnotation3.setBorderStyle(borderStyle3);
        lineAnnotation3.setBorderWidth(5);
        lineAnnotation3.setBorderAlpha(255);
        lineAnnotation3.setBorderColor(Color.BLUE);
        lineAnnotation3.updateAp();
    }

    private void convertLinePoint(CPDFPage page, PointF startPoint, PointF endPoint, RectF area) {
        RectF pageSize = page.getSize();
        float lineWidth = 10f;
        area.left = Math.min(startPoint.x, endPoint.x);
        area.right = Math.max(startPoint.x, endPoint.x);
        area.top = Math.min(startPoint.y, endPoint.y);
        area.bottom = Math.max(startPoint.y, endPoint.y);
        area.left -= lineWidth * 2;
        area.top -= lineWidth * 2;
        area.right += lineWidth * 2;
        area.bottom += lineWidth * 2;
        area.set(page.convertRectToPage(false, pageSize.width(), pageSize.height(), area));
        startPoint.set(page.convertPointToPage(false, pageSize.width(), pageSize.height(), startPoint));
        endPoint.set(page.convertPointToPage(false, pageSize.width(), pageSize.height(), endPoint));
    }

    /**
     * Samples 4 : add circle shape annotation
     *
     * @param document
     */
    private void addCircleShape(CPDFDocument document) {
        // Add a circular annotation with a green border and blue fill
        CPDFPage page3 = document.pageAtIndex(2);
        CPDFCircleAnnotation circleAnnotation = (CPDFCircleAnnotation) page3.addAnnot(CPDFAnnotation.Type.CIRCLE);
        RectF insertRect = getConvertRect(page3, new RectF(50, 50, 150, 150));
        circleAnnotation.setRect(insertRect);
        // set border color
        circleAnnotation.setBorderColor(Color.parseColor("#3863F1"));
        // Set border to solid line
        CPDFBorderStyle borderStyle = new CPDFBorderStyle(CPDFBorderStyle.Style.Border_Solid, 10, new float[]{8.0F, 0F});
        borderStyle.setBorderWidth(5F);
        circleAnnotation.setBorderStyle(borderStyle);
        circleAnnotation.setBorderAlpha(255);
        circleAnnotation.setFillColor(Color.parseColor("#31BC98"));
        circleAnnotation.setFillAlpha(255);
        circleAnnotation.updateAp();

        //Add a circular shape annotation with a dotted border.
        CPDFCircleAnnotation circleAnnotation2 = (CPDFCircleAnnotation) page3.addAnnot(CPDFAnnotation.Type.CIRCLE);
        RectF insertRect2 = getConvertRect(page3, new RectF(50, 200, 150, 300));
        circleAnnotation2.setRect(insertRect2);
        circleAnnotation2.setBorderColor(Color.parseColor("#3863F1"));
        CPDFBorderStyle borderStyle2 = new CPDFBorderStyle(CPDFBorderStyle.Style.Border_Dashed, 10, new float[]{8.0F, 4F});
        borderStyle2.setBorderWidth(5F);
        circleAnnotation2.setBorderStyle(borderStyle2);
        circleAnnotation2.setBorderAlpha(127);
        circleAnnotation2.setFillColor(Color.parseColor("#31BC98"));
        circleAnnotation2.setFillAlpha(127);
        circleAnnotation2.updateAp();
    }

    /**
     * Samples 5 : add square shape annotation
     *
     * @param document
     */
    private void addSquareShape(CPDFDocument document) {
        // Add a rectangle with a blue border and green fill
        CPDFPage page3 = document.pageAtIndex(2);
        CPDFSquareAnnotation squareAnnotation = (CPDFSquareAnnotation) page3.addAnnot(CPDFAnnotation.Type.SQUARE);
        RectF pageSize = page3.getSize();
        RectF insertRect = getConvertRect(page3, new RectF(50, 350, 300, 450));
        squareAnnotation.setRect(insertRect);
        squareAnnotation.setBorderColor(Color.parseColor("#3863F1"));
        CPDFBorderStyle borderStyle = new CPDFBorderStyle(CPDFBorderStyle.Style.Border_Solid, 10, new float[]{8.0F, 0F});
        borderStyle.setBorderWidth(10F);
        squareAnnotation.setBorderStyle(borderStyle);
        squareAnnotation.setBorderAlpha(255);
        squareAnnotation.setFillColor(Color.parseColor("#31BC98"));
        squareAnnotation.setFillAlpha(255);
        squareAnnotation.updateAp();

        // Add a rectangle with a blue dotted border and a green fill with 50% transparency
        CPDFSquareAnnotation squareAnnotation2 = (CPDFSquareAnnotation) page3.addAnnot(CPDFAnnotation.Type.SQUARE);
        RectF insertRect2 = new RectF(50, 500, 300, 600);
        insertRect2 = page3.convertRectToPage(false, pageSize.width(), pageSize.height(), insertRect2);
        squareAnnotation2.setRect(insertRect2);
        squareAnnotation2.setBorderColor(Color.parseColor("#3863F1"));
        CPDFBorderStyle borderStyle2 = new CPDFBorderStyle(CPDFBorderStyle.Style.Border_Dashed, 10, new float[]{8.0F, 4F});
        borderStyle2.setBorderWidth(10F);
        squareAnnotation2.setBorderStyle(borderStyle2);
        squareAnnotation2.setBorderAlpha(127);
        squareAnnotation2.setFillColor(Color.parseColor("#31BC98"));
        squareAnnotation2.setFillAlpha(127);
        squareAnnotation2.updateAp();
    }

    /**
     * Samples 6 : add high annotation
     * Here is a demonstration of searching out keywords in the search page and adding highlighted annotation
     *
     * @param document
     */
    private void addHighlight(CPDFDocument document) {
        //Also search for the `Page` keyword in the 3rd of the document
        CPDFPage pdfPage = document.pageAtIndex(3);
        //Then, add a highlight annotation for the specific area.
        RectF annotRect = new RectF(315, 258, 372, 288);
        annotRect = pdfPage.convertRectToPage(false, pdfPage.getSize().width(), pdfPage.getSize().height(), annotRect);
        CPDFHighlightAnnotation highlightAnnotation = (CPDFHighlightAnnotation) pdfPage.addAnnot(CPDFAnnotation.Type.HIGHLIGHT);
        highlightAnnotation.setColor(Color.YELLOW);
        highlightAnnotation.setAlpha((255 / 2));
        highlightAnnotation.setQuadRects(new RectF[]{annotRect});
        highlightAnnotation.setMarkedText("Page");
        highlightAnnotation.setRect(annotRect);
        highlightAnnotation.updateAp();
        outputListener.println(annotRect.toString());
    }


    /**
     * Samples 7 : add link annotation
     *
     * @param document
     */
    private void addLink(CPDFDocument document) {
        CPDFPage page = document.pageAtIndex(3);
        CPDFLinkAnnotation linkAnnotation = (CPDFLinkAnnotation) page.addAnnot(CPDFAnnotation.Type.LINK);
        RectF insertRect = getConvertRect(page, new RectF(50, 50, 150, 150));
        linkAnnotation.setRect(insertRect);
        float firstPageHeight = document.getPageSize(0).height();
        // Add page jump link action
        CPDFGoToAction goToAction = new CPDFGoToAction();
        CPDFDestination destination = new CPDFDestination(1, 0, firstPageHeight, 1f);
        goToAction.setDestination(document, destination);
        linkAnnotation.setLinkAction(goToAction);
        linkAnnotation.updateAp();
    }

    /**
     * Samples 8 : add note annotation
     *
     * @param document
     */
    private void addNote(CPDFDocument document) {
        CPDFPage page = document.pageAtIndex(3);
        CPDFTextAnnotation textAnnotation = (CPDFTextAnnotation) page.addAnnot(CPDFAnnotation.Type.TEXT);
        //get the actual size of the page you want to insert
        RectF insertRect = getConvertRect(page, new RectF(50, 200, 100, 250));
        textAnnotation.setRect(insertRect);
        textAnnotation.setContent("ComPDF");
        textAnnotation.updateAp();
    }

    /**
     * Samples 9 : add sound annotation
     *
     * @param document
     */
    private void addSound(CPDFDocument document) {
        CPDFPage page = document.pageAtIndex(3);
        CPDFSoundAnnotation soundAnnotation = (CPDFSoundAnnotation) page.addAnnot(CPDFAnnotation.Type.SOUND);
        RectF insertRect = getConvertRect(page, new RectF(50, 300, 100, 350));
        soundAnnotation.setRect(insertRect);
        soundAnnotation.setSoundPath(FileUtils.getAssetsTempFile(SampleApplication.getInstance(), "Bird.wav"));
        soundAnnotation.updateAp();
    }

    /**
     * Samples 10 : add stamp annotation
     *
     * @param document
     */
    private void addStamp(CPDFDocument document) {
        // add standard stamp annotation
        int yOffset = 50;
        float lastOffset = 0;
        for (int i = 0; i < CPDFStampAnnotation.StandardStamp.values().length; i++) {
            CPDFPage page = document.pageAtIndex(4);
            CPDFStampAnnotation.StandardStamp standardStamp = CPDFStampAnnotation.StandardStamp.values()[i];
            if (standardStamp == null || standardStamp == CPDFStampAnnotation.StandardStamp.UNKNOWN) {
                continue;
            }
            // add Standard stamp
            CPDFStampAnnotation standard = (CPDFStampAnnotation) page.addAnnot(CPDFAnnotation.Type.STAMP);
            if (standard == null) {
                continue;
            }
            standard.setStandardStamp(standardStamp);
            RectF pageSize = page.getSize();
            RectF insertRect = standard.getRect();
            insertRect.set(page.convertRectFromPage(false, pageSize.width(), pageSize.height(), insertRect));
            float defaultWidth = 100F;
            int x = 50;
            if (i == 10) {
                lastOffset = 50;
            }
            if (i >= 10) {
                x = 150;
            }
            yOffset = (int) lastOffset + 10;
            PointF vertex = new PointF(x, yOffset);
            insertRect.set(vertex.x, vertex.y, vertex.x + defaultWidth, vertex.y + defaultWidth * Math.abs(insertRect.height() / insertRect.width()));
            lastOffset = insertRect.bottom;
            standard.setRect(page.convertRectToPage(false, pageSize.width(), pageSize.height(), insertRect));
            standard.updateAp();
        }

        //add text stamp annotations
        CPDFPage page = document.pageAtIndex(4);
        CPDFStampAnnotation stampAnnotation = (CPDFStampAnnotation) page.addAnnot(CPDFAnnotation.Type.STAMP);
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = df.format(new Date());
        stampAnnotation.setTextStamp(new CPDFStampAnnotation.TextStamp(
                "ComPDF", date, CPDFStampAnnotation.TextStampShape.TEXTSTAMP_RECT.id,
                CPDFStampAnnotation.TextStampColor.TEXTSTAMP_GREEN.id));
        RectF pageSize = page.getSize();
        RectF insertRect = stampAnnotation.getRect();
        insertRect.set(page.convertRectFromPage(false, pageSize.width(), pageSize.height(), insertRect));
        float defaultWidth = 150f;
        PointF vertex = new PointF(300, 50);
        insertRect.set(vertex.x, vertex.y, vertex.x + defaultWidth, vertex.y + defaultWidth * Math.abs(insertRect.height() / insertRect.width()));
        stampAnnotation.setRect(page.convertRectToPage(false, pageSize.width(), pageSize.height(), insertRect));
        stampAnnotation.updateAp();

        // add image stamp annotations
        CPDFStampAnnotation standard = (CPDFStampAnnotation) page.addAnnot(CPDFAnnotation.Type.STAMP);
        String imagePath = FileUtils.getAssetsTempFile(context, "ComPDF.png");
        float imageDefaultWidth = 100F;
        PointF imageVertex = new PointF(300, 300);
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(imagePath, options);
        RectF imageInsertRect = new RectF(imageVertex.x, imageVertex.y, imageVertex.x + imageDefaultWidth, imageVertex.y + imageDefaultWidth * options.outHeight / options.outWidth);
        RectF pageSize1 = page.getSize();
        imageInsertRect.set(page.convertRectToPage(false, pageSize1.width(), pageSize1.height(), imageInsertRect));
        standard.setRect(imageInsertRect);
        if (imagePath.endsWith("png")) {
            BitmapFactory.Options tmpOptions = new BitmapFactory.Options();
            tmpOptions.inMutable = true;
            Bitmap bitmap = BitmapFactory.decodeFile(imagePath, tmpOptions);
            standard.updateApWithBitmap(bitmap);
            bitmap.recycle();
        } else {
            standard.setImageStamp(imagePath);
            standard.updateAp();
        }
    }

    private RectF getConvertRect(CPDFPage page, RectF rectF) {
        RectF size = page.getSize();
        return page.convertRectToPage(false, size.width(), size.height(), rectF);
    }

    /**
     * Samples 10 : print annotation list info
     */
    private void printAnnotationList() {
        printDividingLine();
        File sampleFile = new File(outputDir(), "AnnotationTest/CreateAnnotationTest.pdf");
        CPDFDocument document = new CPDFDocument(context);
        document.open(sampleFile.getAbsolutePath());
        for (int i = 0; i < document.getPageCount(); i++) {
            CPDFPage page = document.pageAtIndex(i);
            for (CPDFAnnotation annotation : page.getAnnotations()) {
                outputListener.println("Page: " + (i + 1));
                outputListener.println("Annot Type: " + annotation.getType().name());
                RectF widgetRect = annotation.getRect();
                RectF position = page.convertRectFromPage(false, document.getPageSize(i).width(),
                        document.getPageSize(i).height(), widgetRect);
                outputListener.println(String.format("Position: %d, %d, %d, %d", (int) position.left, (int) position.top,
                        (int) position.right, (int) position.bottom));
                printDividingLine();
            }
        }
        document.close();
    }

    /**
     * Samples 11 : delete annotation
     */
    private void deleteAnnotation() {
        File sampleFile = new File(outputDir(), "AnnotationTest/CreateAnnotationTest.pdf");
        CPDFDocument document = new CPDFDocument(context);
        document.open(sampleFile.getAbsolutePath());
        for (int i = 0; i < document.getPageCount(); i++) {
            CPDFPage page = document.pageAtIndex(i);
            List<CPDFAnnotation> annotations = page.getAnnotations();
            if (annotations != null && annotations.size() > 0) {
                page.deleteAnnotation(annotations.get(0));
                break;
            }
        }
        File file = new File(outputDir(), "AnnotationTest/DeleteAnnotationTest.pdf");
        saveSamplePDF(document, file, true);
        outputListener.println("Done.");
        outputListener.println("Done. Results saved in DeleteAnnotationTest.pdf");
    }
}