Back to Blog

    Developer Blog

    How to Annotate PDFs using Foxit PDF SDK (Objective-C)

    Foxit PDF SDK for Mac

    General

    An annotation associates an object such as note, line, and highlight with a location on a page of a PDF document. It provides a way to interact with users by means of the mouse and keyboard. PDF includes a wide variety of standard annotation types as listed in Table 3-1. Among these annotation types, many of them are defined as markup annotations for they are used primarily to mark up PDF documents. These annotations have text that appears as part of the annotation and may be displayed in other ways by a conforming reader, such as in a Comments pane. The ‘Markup’ column in Table 3-1 shows whether an annotation is a markup annotation.

    Foxit PDF SDK supports most annotation types defined in PDF reference. PDF SDK provides APIs of annotation creation, properties access and modification, appearance setting and drawing.

    Table 3-1

    Annotation type Description Markup Supported by SDK
    Text(Note) Text annotation Yes Yes
    Link Link Annotation No Yes
    FreeText
    (TypeWriter/TextBox/Callout)
    Free text annotation Yes Yes
    Line Line annotation Yes Yes
    Square Square annotation Yes Yes
    Circle Circle annotation Yes Yes
    Polygon Polygon annotation Yes Yes
    PolyLine PolyLine annotation Yes Yes
    Highlight Highlight annotation Yes Yes
    Underline Underline annotation Yes Yes
    Squiggly Squiggly annotation Yes Yes
    StrikeOut StrikeOut annotation Yes Yes
    Stamp Stamp annotation Yes Yes
    Caret Caret annotation Yes Yes
    Ink(pencil) Ink annotation Yes Yes
    Popup Popup annotation No Yes
    File Attachment FileAttachment annotation Yes Yes
    Sound Sound annotation Yes No
    Movie Movie annotation No No
    Widget* Widget annotation No Yes
    Screen Screen annotation No Yes
    PrinterMark PrinterMark annotation No No
    TrapNet Trap network annotation No No
    Watermark* Watermark annotation No Yes
    3D 3D annotation No No
    Redact Redact annotation Yes Yes

    Note:

    1. The annotation widget and watermark are special. They aren’t supported in the module of ‘Annotation’. This type of widget is only used in the module as a ‘form filler’ and the watermark in the module of ‘watermark’.
    2. Foxit SDK supports a customized annotation type called PSI (pressure sensitive ink) annotation. Usually, PSI is for handwriting features and Foxit SDK treats it as a PSI annotation so that it can be handled by other PDF products.

    Example:

    How to add a link annotation to another page in the same PDF

    import com.foxit.sdk.pdf.PDFPage;
    import com.foxit.sdk.pdf.annots.Link;
    ...
    // Assuming PDFPage page has been loaded and parsed.
    // Add link annotation
    Link link = new Link(page.addAnnot(Annot.e_Link, new RectF(350, 350, 380, 400)));
    link.setHighlightingMode(Annot.e_HighlightingToggle);
    // Appearance should be reset.
    link.resetAppearanceStream();
    ...
    

    How to add a highlight annotation to a page and set the related annotation properties

    import com.foxit.sdk.pdf.PDFPage;
    import com.foxit.sdk.pdf.annots.Highlight;
    import com.foxit.sdk.common.fxcrt.PointF;
    import com.foxit.sdk.common.fxcrt.PointFArray;
    import com.foxit.sdk.common.fxcrt.RectF;
    import com.foxit.sdk.pdf.annots.QuadPoints;
    import com.foxit.sdk.pdf.annots.QuadPointsArray;
    ...
    // Assuming PDFPage page has been loaded and parsed.
    // Add highlight annotation
    Highlight highlight = new Highlight(page.addAnnot(Annot.e_Highlight, new RectF(10, 450, 100, 550)));
    highlight.setContent("Highlight");
    QuadPoints quad_points = new QuadPoints();
    quad_points.setFirst(new PointF(10, 500));
    quad_points.setSecond(new PointF(90, 500));
    quad_points.setThird(new PointF(10, 480));
    quad_points.setFourth(new PointF(90, 480));
    QuadPointsArray quad_points_array = new QuadPointsArray();
    quad_points_array.add(quad_points);
    highlight.setQuadPoints(quad_points_array);
    highlight.setSubject("Highlight");
    highlight.setTitle("Foxit SDK");
    highlight.setCreationDateTime(GetLocalDateTime());
    highlight.setModifiedDateTime(GetLocalDateTime());
    highlight.setUniqueID(RandomUID());
    // Appearance should be reset.
    highlight.resetAppearanceStream();
    ...
    

    How to set the popup information when creating markup annotations

    import com.foxit.sdk.pdf.PDFPage;
    import com.foxit.sdk.pdf.annots.Note;
    import com.foxit.sdk.pdf.annots.Popup;
    import com.foxit.sdk.common.fxcrt.RectF;
    ...
    // Assuming PDFPage page has been loaded and parsed.
    // Add note annotation
    Note note = new Note(page.addAnnot(Annot.e_Note, new RectF(10, 350, 50, 400)));
    note.setIconName("Comment");
    note.setSubject("Note");
    note.setTitle("Foxit SDK");
    note.setContent("Note annotation.");
    note.setCreationDateTime(GetLocalDateTime());
    note.setModifiedDateTime(GetLocalDateTime());
    note.setUniqueID(RandomUID());
    // Add popup to note annotation
    Popup popup = new Popup(page.addAnnot(Annot.e_Popup, new RectF(300, 450, 500, 550)));
    popup.setBorderColor(0x00FF00);
    popup.setOpenStatus(false);
    popup.setModifiedDateTime(GetLocalDateTime());
    note.setPopup(popup);
    // Appearance should be reset.
    note.resetAppearanceStream();
    ...
    

    How to get page transformation matrix between PDF page coordinates and rendering device coordinates

    import com.foxit.sdk.pdf.PDFPage;
    import com.foxit.sdk.common.fxcrt.RectF;
    import com.foxit.sdk.common.fxcrt.Matrix2D;
    // Assuming PDFDoc doc has been loaded.
    // Assuming PDFPage page has been loaded and parsed.
    ...
    Matrix2D mtx = page.getDisplayMatrix(0, 0, width, height, page.getRotation());
    RectF srcRc = new RectF(100, 200, 200, 100);
    RectF pageRc = new RectF(100, 200, 200, 100);
    mtx.transformRect(pageRc);
    RectF devRc = new RectF(pageRc.getLeft(), pageRc.getBottom(), pageRc.getRight(), pageRc.getTop());
    Matrix2D reverse_mtx = new Matrix2D();
    reverse_mtx.setReverse(mtx);
    reverse_mtx.transformRect(devRc);
    ...
    

    Import annotations from or export annotations to an FDF file

    With Foxit PDF SDK, annotations can be created with data not only from applications but also from FDF files. At the same time, PDF SDK supports annotation exporting to FDF files.

    Example:

    How to load annotations from a FDF file and add them into the first page of a given PDF

    import com.foxit.sdk.common.Range;
    import com.foxit.sdk.fdf.FDFDoc;
    import com.foxit.sdk.pdf.PDFDoc;
    import static com.foxit.sdk.pdf.PDFDoc.e_Annots;
    // Assuming PDFDoc doc has been loaded.
    ...
    Range empty_range = new Range();
    {
    String input_file = input_path + "AboutFoxit.pdf";
    String fdf_file = input_path + "AnnotationData.fdf";
    PDFDoc pdf_doc = new PDFDoc(input_file);
    error_code = pdf_doc.load(null);
    if (error_code != e_ErrSuccess) {
    System.out.println("The Doc " + input_file + " Error: " + error_code);
    return;
    }
    FDFDoc fdf_doc = new FDFDoc(fdf_file);
    pdf_doc.importFromFDF(fdf_doc, e_Annots, empty_range);
    }
    ...
    

    Image Conversion

    Foxit PDF SDK provides APIs for conversion between PDF files and images. Applications could easily fulfill functionalities like image creation and image conversion which supports the following image formats: BMP, TIFF, PNG, JPX, JPEG, and GIF. Foxit PDF SDK can make the conversion between PDF files and the supported image formats except for GIF. It only supports converting GIF images to PDF files.

    Example:

    How to convert PDF pages to bitmap files.

    import com.foxit.sdk.common.Bitmap;
    import com.foxit.sdk.common.Image;
    import com.foxit.sdk.common.Renderer;
    import com.foxit.sdk.common.fxcrt.Matrix2D;
    import com.foxit.sdk.pdf.PDFDoc;
    import com.foxit.sdk.pdf.PDFPage;
    import static com.foxit.sdk.common.Bitmap.e_DIBArgb;
    import static com.foxit.sdk.pdf.PDFPage.e_ParsePageNormal;
    // Assuming PDFDoc doc has been loaded.
    ...
    Image image = new Image();
    // Get page count
    int nPageCount = doc.getPageCount();
    for (int i = 0; i < nPageCount; i++) {
    PDFPage page = doc.getPage(i);
    // Parse page.
    page.startParse(e_ParsePageNormal, null, false);
    int width = (int) page.getWidth();
    int height = (int) page.getHeight();
    Matrix2D matrix = page.getDisplayMatrix(0, 0, width, height, page.getRotation());
    // Prepare a bitmap for rendering.
    Bitmap bitmap = new Bitmap(width, height, e_DIBArgb, null, 0);
    bitmap.fillRect(0xFFFFFFFF, null);
    // Render page.
    Renderer render = new Renderer(bitmap, false);
    render.startRender(page, matrix, null);
    image.addFrame(bitmap);
    }
    ...
    

    How to convert a image file to PDF file

    import com.foxit.sdk.common.Image;
    import com.foxit.sdk.common.fxcrt.PointF;
    import com.foxit.sdk.pdf.PDFDoc;
    import com.foxit.sdk.pdf.PDFPage;
    import static com.foxit.sdk.pdf.PDFPage.e_ParsePageNormal;
    import static com.foxit.sdk.pdf.PDFPage.e_SaveFlagNoOriginal;
    Image image = new Image(input_file);
    int count = image.getFrameCount();
    PDFDoc doc = new PDFDoc();
    for (int i = 0; i < count; i++) {
    PDFPage page = doc.insertPage(i, PDFPage.e_SizeLetter);
    page.startParse(e_ParsePageNormal, null, false);
    // Add image to page.
    page.addImage(image, i, new PointF(0, 0), page.getWidth(), page.getHeight(), true);
    }
    doc.saveAs("convertedPDF.pdf", e_SaveFlagNoOriginal);
    ...