Skip to content
ComPDF
Guides

Create Annotations

ComPDF supports a wide range of annotation types, including notes, links, shapes, highlights, stamps, freehand drawings, and audio annotations, catering to diverse annotation requirements.

Create Note Annotations

Note annotations appear as small icons or labels. When clicked by the user, they can expand to display relevant annotation content. This annotation type is used for adding personal notes, reminders, or comments, allowing users to add personalized additional information to the document without affecting the readability of the original text.

Programmatic Creation

The steps to create a note are as follows:

  1. Obtain the page object where the annotation needs to be created.

  2. Create a note annotation object on that page.

  3. Set the annotation properties.

  4. Update the annotation appearance to display it on the document.

This example shows how to create note annotations:

Java
// Insert page numbers.
int pageNumber = 0;
// Retrieve an instance of the PDF page.
CPDFPage page = document.pageAtIndex(pageNumber);
CPDFTextAnnotation textAnnotation = (CPDFTextAnnotation) page.addAnnot(CPDFAnnotation.Type.TEXT);
// Retrieve the actual size of the page to be inserted.
RectF pageSize = page.getSize();
RectF insertRect = new RectF(0, 0, 50, 50);
// Coordinate transformation.
insertRect = page.convertRectToPage(
  false,
  pageSize.width(),
  pageSize.height(),
  insertRect);
textAnnotation.setColor(Color.RED);
textAnnotation.setAlpha(255);
textAnnotation.setRect(insertRect);
textAnnotation.setContent("ComPDF");
textAnnotation.updateAp();
kotlin
// Insert page numbers.
val pageNumber = 0
// Retrieve an instance of the PDF page.
val page = document.pageAtIndex(pageNumber)
val textAnnotation = page.addAnnot(CPDFAnnotation.Type.TEXT) as CPDFTextAnnotation
// Retrieve the actual size of the page to be inserted.
val pageSize = page.size
// Coordinate transformation.
val insertRect = page.convertRectToPage(
  false,
  pageSize.width(),
  pageSize.height(),
  RectF(0f, 0f, 50f, 50f)
)
textAnnotation.setColor(Color.RED)
textAnnotation.alpha = 255
textAnnotation.rect = insertRect
textAnnotation.content = "ComPDF"
textAnnotation.updateAp()

Synchronizing with ReaderView

If the PDF is currently displayed using CPDFReaderView, and the target page is loaded or visible, you need to add the annotation to the corresponding CPDFPageView for immediate display.

Only pages that are currently displayed or about to be displayed have a CPDFPageView. Always check for null.

java
CPDFPageView pageView =
        (CPDFPageView) readerView.getChild(pageIndex);

if (pageView != null) {
    boolean isFocused = false;
    pageView.addAnnotation(textAnnotation, isFocused);
}
kotlin
val pageView = readerView.getChild(pageIndex) as? CPDFPageView

pageView?.let {
    val isFocused = false
    it.addAnnotation(textAnnotation, isFocused)
}

Interactive Creation

This applies to user-added text annotations in reading or editing mode. Users can tap a page to add a text annotation and a custom popup allows editing the annotation content.

Process:

  1. Switch CPDFReaderView to annotation mode
  2. Enable the touch mode for adding text annotations
  3. User taps a page to create the annotation
  4. A custom editor popup appears for input
  5. After saving or deleting, exit annotation mode
java
// 1. Enter annotation mode
readerView.setViewMode(CPDFReaderView.ViewMode.ANNOT);

// 2. Enable text annotation adding mode
readerView.setTouchMode(CPDFReaderView.TouchMode.ADD_ANNOT);
readerView.setCurrentFocusedType(CPDFAnnotation.Type.TEXT);

// 3. Exit annotation mode
readerView.setTouchMode(CPDFReaderView.TouchMode.BROWSE);
readerView.setCurrentFocusedType(CPDFAnnotation.Type.UNKNOWN);

Custom Popup Editor

To show a popup editor for text annotations, extend CPDFTextAnnotAttachHelper and override onAddTextAnnot:

java
public class CustomTextAnnotAttachHelper extends CPDFTextAnnotAttachHelper {
    @Override
    protected void onAddTextAnnot(CPDFTextAnnotImpl cpdfTextAnnot) {
        cpdfTextAnnot.setFocused(true);

        // Create custom edit dialog
        CNoteEditDialog editDialog = CNoteEditDialog.newInstance("");
        editDialog.setDismissListener(() -> {
            String content = editDialog.getContent();
            cpdfTextAnnot.onGetAnnotation().setContent(content);
        });

        editDialog.setSaveListener(v -> {
            // Save text annotation content
            String content = editDialog.getContent();
            cpdfTextAnnot.onGetAnnotation().setContent(content);
            editDialog.dismiss();
            pageView.setFocusAnnot(cpdfTextAnnot);

            // Exit annotation mode
            readerView.setCurrentFocusedType(CPDFAnnotation.Type.UNKNOWN);
            readerView.setTouchMode(CPDFReaderView.TouchMode.BROWSE);
        });

        editDialog.setDeleteListener(v -> {
            // Delete the text annotation
            pageView.deleteAnnotation(cpdfTextAnnot);
            editDialog.dismiss();
        });

        FragmentActivity fragmentActivity = CViewUtils.getFragmentActivity(readerView.getContext());
        if (fragmentActivity != null) {
            editDialog.show(fragmentActivity.getSupportFragmentManager(), "noteEditDialog");
        }
    }
}

Register the Custom Text Annotation Helper

java
// After registration, interactive text annotations will directly show the custom popup for editing.
cpdfReaderView
    .getAnnotImplRegistry()
    .registAttachHelper(CPDFTextAnnotation.class, CustomTextAnnotAttachHelper.class);

To make a popup appear when tapping a text annotation, extend CPDFTextAnnotImpl.java and register:

java
cpdfReaderView.getAnnotImplRegistry().registImpl(CPDFTextAnnotation.class, CPDFTextAnnotImpl.class);

Link annotations allow users to navigate directly to other locations within the document or external resources, enhancing the navigation experience.

Programmatic Creation

The steps to create link annotations are as follows:

  1. Obtain the page object where the annotation needs to be created.
  2. Create a link annotation object on that page.
  3. Use CPDFDestination to specify the destination page, for example, jumping to page 2.
  4. Set the annotation properties and attach the CPDFDestination object to the annotation.

This example shows how to create link annotations:

Java
// Insert page numbers.
int pageNumber = 0;
// // Retrieve an instance of the PDF page.
CPDFPage page = document.pageAtIndex(pageNumber);
CPDFLinkAnnotation linkAnnotation = (CPDFLinkAnnotation) page.addAnnot(CPDFAnnotation.Type.LINK);
RectF pageSize = page.getSize();
RectF insertRect = new RectF(0,0,100,100);
// Coordinate transformation.
insertRect = page.convertRectToPage(false , pageSize.width(), pageSize.height(), insertRect);
linkAnnotation.setRect(insertRect);

// Navigate to a specified page number.
CPDFGoToAction goToAction = new CPDFGoToAction();
CPDFDestination destination = new CPDFDestination(pageNumber,0,pageSize.height(),1f);
goToAction.setDestination(document, destination);
linkAnnotation.setLinkAction(goToAction);

// Open a specific webpage.
CPDFUriAction uriAction = new CPDFUriAction();
uriAction.setUri("website");
linkAnnotation.setLinkAction(uriAction);
// Update the annotations onto the document.
linkAnnotation.updateAp();
kotlin
// Insert page numbers.
val pageNumber = 0
// Retrieve an instance of the PDF page.
val page = document.pageAtIndex(pageNumber)
val linkAnnotation = page.addAnnot(CPDFAnnotation.Type.LINK) as CPDFLinkAnnotation
val pageSize = page.size
// Coordinate transformation.
linkAnnotation.rect = run {
  var insertRect: RectF? = RectF(0F, 0F, 100F, 100F)
  page.convertRectToPage(false, pageSize.width(), pageSize.height(), insertRect)
}

// Navigate to a specified page number.
linkAnnotation.linkAction = CPDFGoToAction().apply {
  setDestination(document,  CPDFDestination(pageNumber, 0F, pageSize.height(), 1F))
}

// Open a specific webpage.
linkAnnotation.linkAction = CPDFUriAction().apply {
  uri = "website"
}
// Update the annotations onto the document.
linkAnnotation.updateAp()

Synchronizing with ReaderView

If the PDF is currently displayed via CPDFReaderView and the target page is loaded or visible, you need to add the annotation to the corresponding CPDFPageView for immediate display.

Only pages that are displayed or about to be displayed have a CPDFPageView. Always check for null.

java
CPDFPageView pageView = (CPDFPageView) readerView.getChild(pageIndex);

if (pageView != null) {
    boolean isFocused = false;
    pageView.addAnnotation(annotation, isFocused);
}
kotlin
val pageView = readerView.getChild(pageIndex) as? CPDFPageView

pageView?.let {
    val isFocused = false
    it.addAnnotation(annotation, isFocused)
}

Interactive Creation

This applies to user-added link annotations in reading or editing mode. Users can select a rectangle on the PDF page and a custom popup allows editing the link target.

Process:

  1. Switch CPDFReaderView to annotation mode
  2. Enable the touch mode for adding link annotations
  3. User selects a page area to create the annotation
  4. A custom editor popup appears for input
  5. Exit annotation mode
java
// 1. Enter annotation mode
readerView.setViewMode(CPDFReaderView.ViewMode.ANNOT);

// 2. Enable link annotation adding mode
readerView.setTouchMode(CPDFReaderView.TouchMode.ADD_ANNOT);
readerView.setCurrentFocusedType(CPDFAnnotation.Type.Link);

// 3. Exit annotation mode
readerView.setTouchMode(CPDFReaderView.TouchMode.BROWSE);
readerView.setCurrentFocusedType(CPDFAnnotation.Type.UNKNOWN);

Custom Popup Editor

To show a popup for link annotation settings, extend CPDFLinkAnnotAttachHelper and override setLinkAction:

java
public class CLinkAnnotAttachHelper extends CPDFLinkAnnotAttachHelper {

    @Override
    public void setLinkAction(CPDFLinkAnnotation linkAnnotation) {
        super.setLinkAction(linkAnnotation);
        if (linkAnnotation == null || !linkAnnotation.isValid()) return;

        // Create and display the edit dialog
        CActionEditDialogFragment editDialog = CActionEditDialogFragment.newInstance(
                readerView.getPDFDocument().getPageCount()
        );

        editDialog.setOnLinkInfoChangeListener(new CActionEditDialogFragment.COnActionInfoChangeListener() {
            @Override
            public void cancel() {
                // Delete annotation if canceled
                pageView.deleteAnnotation(linkAnnotation);
            }

            @Override
            public void createWebsiteLink(String url) {
                // Attach website link
                CPDFUriAction action = new CPDFUriAction();
                action.setUri(url);
                linkAnnotation.setLinkAction(action);
                pageView.addAnnotation(linkAnnotation, false);
            }

            @Override
            public void createEmailLink(String email) {
                CPDFUriAction action = new CPDFUriAction();
                action.setUri(email);
                linkAnnotation.setLinkAction(action);
                pageView.addAnnotation(linkAnnotation, false);
            }

            @Override
            public void createPageLink(int page) {
                CPDFGoToAction action = new CPDFGoToAction();
                CPDFDestination dest = new CPDFDestination(page - 1, 0f,
                        readerView.getPDFDocument().pageAtIndex(page - 1).getSize().height(), 1f);
                action.setDestination(readerView.getPDFDocument(), dest);
                linkAnnotation.setLinkAction(action);
                pageView.addAnnotation(linkAnnotation, false);
            }
        });

        FragmentActivity activity = CViewUtils.getFragmentActivity(readerView.getContext());
        if (activity != null) {
            editDialog.show(activity.getSupportFragmentManager(), "linkDialog");
        }
    }
}
kotlin
class CLinkAnnotAttachHelper : CPDFLinkAnnotAttachHelper() {

    override fun setLinkAction(linkAnnotation: CPDFLinkAnnotation?) {
        super.setLinkAction(linkAnnotation)
        if (linkAnnotation == null || !linkAnnotation.isValid) return

        // Create and display edit dialog
        val editDialog = CActionEditDialogFragment.newInstance(readerView.pdfDocument.pageCount)

        editDialog.setOnLinkInfoChangeListener(object : CActionEditDialogFragment.COnActionInfoChangeListener {
            override fun cancel() {
                // Delete annotation if canceled
                pageView?.deleteAnnotation(linkAnnotation)
            }

            override fun createWebsiteLink(url: String) {
                val action = CPDFUriAction().apply { this.uri = url }
                linkAnnotation.linkAction = action
                pageView?.addAnnotation(linkAnnotation, false)
            }

            override fun createEmailLink(email: String) {
                val action = CPDFUriAction().apply { this.uri = email }
                linkAnnotation.linkAction = action
                pageView?.addAnnotation(linkAnnotation, false)
            }

            override fun createPageLink(page: Int) {
                val action = CPDFGoToAction()
                val document = readerView.pdfDocument
                val height = document.pageAtIndex(page - 1).size.height()
                val destination = CPDFDestination(page - 1, 0f, height, 1f)
                action.setDestination(document, destination)
                linkAnnotation.linkAction = action
                pageView?.addAnnotation(linkAnnotation, false)
            }
        })

        CViewUtils.getFragmentActivity(readerView.context)?.let { activity ->
            editDialog.show(activity.supportFragmentManager, "linkDialog")
        }
    }
}

Register the Custom Link Annotation Helper

java
// After registration, interactive link annotations will directly show the custom popup for editing.
cpdfReaderView
    .getAnnotImplRegistry()
    .registAttachHelper(CPDFLinkAnnotation.class, CLinkAnnotAttachHelper.class);

Create Free Text Annotations

Free text annotations enable users to insert free-form text into PDF documents, serving the purpose of adding annotations, comments, or explanations to document content.

Programmatic Creation

The steps to create a free text annotation are as follows:

  1. Obtain the page object where the annotation needs to be created.

  2. Create a free text annotation object on that page.

  3. Set the annotation properties.

  4. Update the annotation appearance to display it on the document.

This example shows how to create free text annotations:

java
// Insert page numbers.
int pageNumber = 0;
// Retrieve an instance of the PDF page.
CPDFPage page = document.pageAtIndex(pageNumber);
CPDFFreetextAnnotation freetextAnnotation = (CPDFFreetextAnnotation) page.addAnnot(CPDFAnnotation.Type.FREETEXT);
RectF pageSize = page.getSize();
RectF insertRect = new RectF(0F,0F,100F,100F);
// Coordinate transformation.
insertRect = page.convertRectToPage(false,pageSize.width(),pageSize.height(),insertRect);
freetextAnnotation.setRect(insertRect);
// Set annotation properties
freetextAnnotation.setContent("ComPDF Samples");
freetextAnnotation.setFreetextAlignment(CPDFFreetextAnnotation.Alignment.ALIGNMENT_CENTER);
CPDFTextAttribute textAttribute = new CPDFTextAttribute(CPDFTextAttribute.FontNameHelper.obtainFontName(
  CPDFTextAttribute.FontNameHelper.FontType.Helvetica, false, false
), 12, Color.RED);
freetextAnnotation.setFreetextDa(textAttribute);
// Update the annotations onto the document.
freetextAnnotation.updateAp();
kotlin
// Insert page numbers.
val pageNumber = 0
// Retrieve an instance of the PDF page.
val page = document.pageAtIndex(pageNumber)
(page.addAnnot(CPDFAnnotation.Type.FREETEXT) as CPDFFreetextAnnotation).apply {
  // Coordinate transformation.
  val size = page.size
  rect = page.convertRectToPage(false, size.width(), size.height(),  RectF(0f, 0f, 100f, 100f))
  // Set annotation properties
  freetextAlignment = CPDFFreetextAnnotation.Alignment.ALIGNMENT_CENTER
  freetextDa = CPDFTextAttribute(CPDFTextAttribute.FontNameHelper.obtainFontName(
    CPDFTextAttribute.FontNameHelper.FontType.Courier, false, false
  ), 12f, Color.RED)
  alpha = 255
  content = "ComPDF Samples"
  // Update the annotations onto the document.
  updateAp()
}

Synchronizing with ReaderView

If the PDF is currently displayed via CPDFReaderView and the target page is loaded or visible, you need to add the annotation to the corresponding CPDFPageView for it to immediately appear in the UI.

Only pages that are displayed or about to be displayed have a CPDFPageView. Always check for null.

java
CPDFPageView pageView = (CPDFPageView) readerView.getChild(pageIndex);

if (pageView != null) {
    boolean isFocused = false;
    pageView.addAnnotation(annotation, isFocused);
}
kotlin
val pageView = readerView.getChild(pageIndex) as? CPDFPageView

pageView?.let {
    val isFocused = false
    it.addAnnotation(annotation, isFocused)
}

Interactive Creation

This applies to user-added FreeText annotations. Users can click anywhere on a PDF page to create a text annotation.

Workflow:

  1. Switch CPDFReaderView to annotation mode
  2. Enable the touch mode for adding FreeText annotations
  3. User taps a page area to create a FreeText input box
  4. Soft keyboard appears for input
  5. Exit annotation mode

Example:

java
// 1. Enter annotation mode
readerView.setViewMode(CPDFReaderView.ViewMode.ANNOT);

// 2. Enable FreeText annotation adding mode
readerView.setTouchMode(CPDFReaderView.TouchMode.ADD_ANNOT);
readerView.setCurrentFocusedType(CPDFAnnotation.Type.FREETEXT);

// 3. Exit annotation mode
readerView.setTouchMode(CPDFReaderView.TouchMode.BROWSE);
readerView.setCurrentFocusedType(CPDFAnnotation.Type.UNKNOWN);

Create Shape Annotations

Graphic annotations encompass shapes such as rectangles, circles, lines, and arrows, used to draw attention to or highlight specific areas in a document, conveying information that may be challenging to describe with text alone.

Programmatic Creation

The steps to create graphic annotations are as follows:

  1. Obtain the page object where the annotations need to be created.

  2. Sequentially create rectangle, circle, and line annotations on that page.

  3. Set the annotation properties.

  4. Sequentially update the annotation appearance to display them on the document.

This example shows how to create shape annotations:

Java
// Insert page numbers.
int pageNumber = 0;
// Retrieve an instance of the PDF page.
CPDFPage page = document.pageAtIndex(pageNumber);

// Create a rectangle annotation object on the page.
CPDFSquareAnnotation squareAnnotation = (CPDFSquareAnnotation) page.addAnnot(CPDFAnnotation.Type.SQUARE);
RectF pageSize = page.getSize();
RectF insertRect = new RectF(0,0,100,100);
// Coordinate transformation.
insertRect = page.convertRectToPage(false,pageSize.width(),pageSize.height(),insertRect);
squareAnnotation.setRect(insertRect);
// Set annotation properties.
squareAnnotation.setBorderColor(Color.YELLOW);
CPDFBorderStyle borderStyle = new CPDFBorderStyle(CPDFBorderStyle.Style.Border_Solid, 10, new float[]{8.0F, 0F});
squareAnnotation.setBorderStyle(borderStyle);
squareAnnotation.setBorderAlpha(255);
squareAnnotation.setFillColor(Color.RED);
squareAnnotation.setFillAlpha(255);
// Update the annotations onto the document.
squareAnnotation.updateAp();


// Create a circular annotation object on the page.
CPDFCircleAnnotation circleAnnotation = (CPDFCircleAnnotation) page.addAnnot(CPDFAnnotation.Type.CIRCLE);
RectF pageSize = page.getSize();
RectF insertRect = new RectF(0,0,100,100);
// Coordinate transformation.
insertRect = page.convertRectToPage(false,pageSize.width(),pageSize.height(),insertRect);
circleAnnotation.setRect(insertRect);
// Set annotation properties.
circleAnnotation.setBorderColor(Color.YELLOW);
CPDFBorderStyle borderStyle = new CPDFBorderStyle(CPDFBorderStyle.Style.Border_Solid, 10, new float[]{8.0F, 0F});
circleAnnotation.setBorderStyle(borderStyle);
circleAnnotation.setBorderAlpha(255);
circleAnnotation.setFillColor(Color.RED);
circleAnnotation.setFillAlpha(255);
// Update the annotations onto the document.
circleAnnotation.updateAp();


// Create a line annotation object on the page.
CPDFLineAnnotation lineAnnotation = (CPDFLineAnnotation) page.addAnnot(CPDFAnnotation.Type.LINE);
float lineWidth = 10f;
RectF pageSize = page.getSize();
// Coordinate transformation.
PointF startPoint = new PointF(0,0);
PointF endPoint = new PointF(200,200);
RectF area = new RectF();
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));
lineAnnotation.setRect(area);
lineAnnotation.setLinePoints(startPoint, endPoint);
// Set annotation properties.
lineAnnotation.setLineType(CPDFLineAnnotation.LineType.LINETYPE_NONE, CPDFLineAnnotation.LineType.LINETYPE_ARROW);
CPDFBorderStyle borderStyle = new CPDFBorderStyle(CPDFBorderStyle.Style.Border_Solid,lineWidth,null);
lineAnnotation.setBorderStyle(borderStyle);
lineAnnotation.setBorderWidth(10F);
lineAnnotation.setBorderAlpha(255);
lineAnnotation.setBorderColor(Color.RED);
// Update the annotations onto the document.
lineAnnotation.updateAp();
kotlin
// Insert page numbers.
val pageNumber = 0
// Retrieve an instance of the PDF page.
val page = document.pageAtIndex(pageNumber)

// Create a rectangle annotation object on the page.
val squareAnnotation = page.addAnnot(CPDFAnnotation.Type.SQUARE) as CPDFSquareAnnotation
val pageSize = page.size
// Coordinate transformation.
squareAnnotation.rect = page.convertRectToPage(false, pageSize.width(), pageSize.height(), RectF(0F, 0F, 100F, 100F))

squareAnnotation.apply {
  // Set annotation properties.
  borderColor = Color.YELLOW
  borderStyle = CPDFBorderStyle(CPDFBorderStyle.Style.Border_Solid, 10F, floatArrayOf(8F, 0F))
  borderAlpha = 255
  fillColor = Color.RED
  fillAlpha = 255
}
// Update the annotations onto the document.
squareAnnotation.updateAp()

// Create a circular annotation object on the page.
val circleAnnotation = page.addAnnot(CPDFAnnotation.Type.CIRCLE) as CPDFCircleAnnotation
val pageSize = page.size
// Coordinate transformation.
circleAnnotation.rect = page.convertRectToPage(false, pageSize.width(), pageSize.height(), RectF(0F, 0F, 100F, 100F))
// Set annotation properties.
circleAnnotation.borderColor = Color.YELLOW
circleAnnotation.borderStyle = CPDFBorderStyle(CPDFBorderStyle.Style.Border_Solid, 10F, floatArrayOf(8F, 0F))
circleAnnotation.borderAlpha = 255
circleAnnotation.fillColor = Color.RED
circleAnnotation.fillAlpha = 255
// Update the annotations onto the document.
circleAnnotation.updateAp()

// Create a line annotation object on the page.
val lineAnnotation = page.addAnnot(CPDFAnnotation.Type.LINE) as CPDFLineAnnotation
val lineWidth = 10F
val pageSize = page.size
val startPoint = PointF(0F, 0F)
val endPoint = PointF(200F, 200F)

val area = RectF().apply {
  left = min(startPoint.x, endPoint.x) - lineWidth * 2
  top = min(startPoint.y, endPoint.y) - lineWidth * 2
  right = max(startPoint.x, endPoint.x) + lineWidth * 2
  bottom = max(startPoint.y, endPoint.y) + lineWidth * 2
  set(page.convertRectToPage(false, pageSize.width(), pageSize.height(), this))
}
// Coordinate transformation.
listOf(startPoint, endPoint).forEach { 
  point ->
  point.set(page.convertPointToPage(
    false,
    pageSize.width(),
    pageSize.height(),
    point))
}
// Set annotation properties.
lineAnnotation.rect = area
lineAnnotation.setLinePoints(startPoint, endPoint)
lineAnnotation.setLineType(CPDFLineAnnotation.LineType.LINETYPE_NONE, CPDFLineAnnotation.LineType.LINETYPE_ARROW)
lineAnnotation.borderStyle = CPDFBorderStyle(CPDFBorderStyle.Style.Border_Solid, lineWidth, null)
lineAnnotation.borderAlpha = 255
lineAnnotation.borderColor = Color.RED
// Update the annotations onto the document.
lineAnnotation.updateAp()

Explanation of Line Types

NameDescription
LINETYPE_UNKNOWNNon-standard or invalid line segment endpoint.
LINETYPE_NONENo line segment endpoint.
LINETYPE_ARROWTwo short lines intersect at a sharp angle, forming an open arrow.
LINETYPE_CLOSEDARROWTwo short lines intersect at a sharp angle, similar to style one, and are connected by a third line, forming a triangular closed arrow filled with the interior color of the annotation.
LINETYPE_SQUAREA square filled with the interior color of the annotation.
LINETYPE_CIRCLEA circle filled with the interior color of the annotation.
LINETYPE_DIAMONDA diamond shape filled with the interior color of the annotation.
LINETYPE_BUTTA short line perpendicular to the line itself, located at the endpoint.
LINETYPE_ROPENARROWTwo short lines in opposite directions.
LINETYPE_RCLOSEDARROWA triangular closed arrow in opposite directions.
LINETYPE_SLASHA short line, located at the endpoint, rotated approximately 30 degrees clockwise from the direction perpendicular to the line itself.

ReaderView Synchronization

If the PDF is displayed via CPDFReaderView and the target page is loaded or visible, you need to add the annotation to the corresponding CPDFPageView to make it immediately visible.

Only pages that are displayed or about to be displayed have a CPDFPageView. Always check for null.

java
CPDFPageView pageView = (CPDFPageView) readerView.getChild(pageIndex);

if (pageView != null) {
    boolean isFocused = false;
    pageView.addAnnotation(annotation, isFocused);
}
kotlin
val pageView = readerView.getChild(pageIndex) as? CPDFPageView

pageView?.let {
    val isFocused = false
    it.addAnnotation(annotation, isFocused)
}

Interactive Creation

This applies to user-added shape annotations. Users can click anywhere on a PDF page to create a shape annotation.

Workflow:

  1. Switch CPDFReaderView to annotation mode
  2. Enable the touch mode for adding shape annotations
  3. User draws on the PDF page to create the shape annotation
  4. Exit annotation mode

Example:

java
// 1. Enter annotation mode
readerView.setViewMode(CPDFReaderView.ViewMode.ANNOT);

// 2. Enable shape annotation adding mode
readerView.setTouchMode(CPDFReaderView.TouchMode.ADD_ANNOT);
// Choose type: SQUARE, CIRCLE, LINE
readerView.setCurrentFocusedType(CPDFAnnotation.Type.SQUARE);

// 3. Exit annotation mode
readerView.setTouchMode(CPDFReaderView.TouchMode.BROWSE);
readerView.setCurrentFocusedType(CPDFAnnotation.Type.UNKNOWN);

Create Markup Annotations

Incorporate annotations in a PDF document to highlight, emphasize, or explain specific content, such as important paragraphs, lines, words, keywords, tables, etc. ComPDF provides four types of markup annotations: highlight, underline, squiggly line, and strikethrough.

Programmatic Creation

The steps to create a markup annotation are as follows:

  1. Obtain the page object where the annotation needs to be created.

  2. Create a text object through the page object.

  3. Use the text object to identify the location of the text to be marked.

  4. Create the corresponding markup object on that page.

  5. Set the properties of the markup object.

  6. Update the annotation appearance to display it on the document.

This example shows how to create markup annotations:

Java
// First, retrieve a TextSelection array from a specific region on the page to select text.
CPDFPage pdfPage = document.pageAtIndex(0);
RectF size = pdfPage.getSize();

CPDFTextPage pdfTextPage = pdfPage.getTextPage();
RectF selectRect = new RectF(0f, 0f, 500f, 500f);

selectRect = pdfPage.convertRectFromPage(false, size.width(), size.height(), selectRect);
CPDFTextSelection[] textSelectionArr = pdfTextPage.getSelectionsByLineForRect(selectRect);

// Then, add a highlight annotation to the specific region for highlighting.
RectF annotRect = new RectF();
CPDFHighlightAnnotation highlightAnnotation = (CPDFHighlightAnnotation) pdfPage.addAnnot(CPDFAnnotation.Type.HIGHLIGHT);
highlightAnnotation.setColor(Color.YELLOW);
highlightAnnotation.setAlpha((255 / 4));
RectF[] quadRects = new RectF[textSelectionArr.length];
StringBuilder markedTextSb = new StringBuilder();
int len = textSelectionArr.length;
for (int i = 0; i < len; i++) {
  CPDFTextSelection textSelection = textSelectionArr[i];
  if (textSelection == null) {
    continue;
  }
  RectF rect = new RectF(textSelection.getRectF());
  if (annotRect.isEmpty()) {
    annotRect.set(rect);
  } else {
    annotRect.union(rect);
  }

  quadRects[i] = new RectF(textSelection.getRectF());
  String text = pdfTextPage.getText(textSelection.getTextRange());
  if (!TextUtils.isEmpty(text)) {
    markedTextSb.append(text);
  }
}

highlightAnnotation.setQuadRects(quadRects);
highlightAnnotation.setMarkedText(markedTextSb.toString());
highlightAnnotation.setRect(annotRect);
highlightAnnotation.updateAp();
Kotlin
// First, retrieve a TextSelection array from a specific region on the page to select text.
val page = document.pageAtIndex(0)

val size = page.size
val pdfTextPage = page.textPage
val selectRect = RectF(0f, 0f, 500f, 500f)
val convertedRect = page.convertRectFromPage(false, size.width(), size.height(), selectRect)
val textSelectionArr = pdfTextPage.getSelectionsByLineForRect(convertedRect)

val highlightAnnotation = page.addAnnot(CPDFAnnotation.Type.HIGHLIGHT) as CPDFHighlightAnnotation
highlightAnnotation.color = Color.YELLOW
highlightAnnotation.alpha = 255 / 4

val quadRects = mutableListOf<RectF>()
val markedTextSb = StringBuilder()

// Then, add a highlight annotation to the specific region for highlighting.
val annotRect = RectF()

textSelectionArr.forEach { textSelection ->
    textSelection?.let {
        val rect = RectF(it.rectF)
        if (annotRect.isEmpty) {
            annotRect.set(rect)
        } else {
            annotRect.union(rect)
        }
        quadRects.add(RectF(it.rectF))
        val text = pdfTextPage.getText(it.textRange)
        if (!TextUtils.isEmpty(text)) {
            markedTextSb.append(text)
        }
    }
}

highlightAnnotation.quadRects = quadRects.toTypedArray()
highlightAnnotation.markedText = markedTextSb.toString()
highlightAnnotation.rect = annotRect
highlightAnnotation.updateAp()

Synchronizing with ReaderView

If the PDF is displayed via CPDFReaderView and the target page is loaded or visible, you need to add the annotation to the corresponding CPDFPageView to make it immediately visible.

Only pages that are displayed or about to be displayed have a CPDFPageView. Always check for null.

java
CPDFPageView pageView = (CPDFPageView) readerView.getChild(pageIndex);
if (pageView != null) {
    boolean isFocused = false;
    pageView.addAnnotation(annotation, isFocused);
}
kotlin
val pageView = readerView.getChild(pageIndex) as? CPDFPageView
pageView?.let {
    val isFocused = false
    it.addAnnotation(annotation, isFocused)
}

Interactive Creation

This applies to user-added markup annotations. Users can click anywhere on a PDF page to create a markup annotation.

Workflow:

  1. Switch CPDFReaderView to annotation mode
  2. Enable touch mode for adding markup annotations
  3. User selects text on the PDF page to create the annotation
  4. Exit annotation mode

Example:

java
// 1. Enter annotation mode
readerView.setViewMode(CPDFReaderView.ViewMode.ANNOT);

// 2. Enable markup annotation adding mode
readerView.setTouchMode(CPDFReaderView.TouchMode.ADD_ANNOT);
// HIGHLIGHT, UNDERLINE, STRIKEOUT, SQUIGGLY
readerView.setCurrentFocusedType(CPDFAnnotation.Type.HIGHLIGHT);

// 3. Exit annotation mode
readerView.setTouchMode(CPDFReaderView.TouchMode.BROWSE);
readerView.setCurrentFocusedType(CPDFAnnotation.Type.UNKNOWN);
kotlin
readerView.viewMode = CPDFReaderView.ViewMode.ANNOT
readerView.touchMode = CPDFReaderView.TouchMode.ADD_ANNOT
readerView.currentFocusedType = CPDFAnnotation.Type.HIGHLIGHT

// Exit annotation mode
readerView.touchMode = CPDFReaderView.TouchMode.BROWSE
readerView.currentFocusedType = CPDFAnnotation.Type.UNKNOWN

Create Stamp Annotations

Stamp annotations are used to identify and validate the source and authenticity of a document. ComPDF supports standard stamps, text stamps, and image stamps.

Programmatic Creation

The steps to create a stamp annotation are as follows:

  1. Obtain the page object where the annotation needs to be created.

  2. Create the corresponding stamp on that page.

  3. Set the properties of the stamp.

  4. Update the annotation appearance to display it on the document.

This example shows how to create stamp annotations:

Java
// Retrieve the page object for creating annotations.
int pageNumber = 0;
CPDFPage page = document.pageAtIndex(pageNumber);

// Create a standard stamp.
CPDFStampAnnotation standardStamp = (CPDFStampAnnotation)page.addAnnot(CPDFAnnotation.Type.STAMP);
standardStamp.setStandardStamp(CPDFStampAnnotation.StandardStamp.COMPLETED);
RectF pageSize = page.getSize();
RectF insertRect = standardStamp.getRect();
insertRect.set(page.convertRectFromPage(false, pageSize.width(), pageSize.height(), insertRect));
float defaultWidth = 200f;
PointF vertex = new PointF(0,0);
insertRect.set(vertex.x, vertex.y, vertex.x + defaultWidth, vertex.y + defaultWidth * Math.abs(insertRect.height() / insertRect.width()));
standardStamp.setRect(page.convertRectToPage(false, pageSize.width(), pageSize.height(), insertRect));
standardStamp.updateAp();

// Create a text stamp.
CPDFStampAnnotation textStamp = (CPDFStampAnnotation) page.addAnnot(CPDFAnnotation.Type.STAMP);
textStamp.setTextStamp(new CPDFStampAnnotation.TextStamp("Hello world","2022/01/01 12:00:00", CPDFStampAnnotation.TextStampShape.TEXTSTAMP_RIGHT_TRIANGLE.id, CPDFStampAnnotation.TextStampColor.TEXTSTAMP_GREEN.id));
RectF pageSize = page.getSize();
RectF insertRect = textStamp.getRect();
insertRect.set(page.convertRectFromPage(false, pageSize.width(), pageSize.height(), insertRect));
float defaultWidth = 200F;
PointF vertex = new PointF(0,0);
insertRect.set(vertex.x, vertex.y, vertex.x + defaultWidth, vertex.y + defaultWidth * Math.abs(insertRect.height() / insertRect.width()));
textStamp.setRect(page.convertRectToPage(false, pageSize.width(), pageSize.height(), insertRect));
textStamp.updateAp();

// Create an image stamp.
CPDFStampAnnotation imageStamp = (CPDFStampAnnotation) page.addAnnot(CPDFAnnotation.Type.STAMP);
String imagePath = "imagePath";
float defaultWidth = 200F;
PointF vertex = new PointF(0,0);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(imagePath, options);
RectF insertRect = new RectF(vertex.x, vertex.y, vertex.x + defaultWidth, vertex.y + defaultWidth * options.outHeight / options.outWidth);
RectF pageSize =page.getSize();
insertRect.set(page.convertRectToPage(false, pageSize.width(), pageSize.height(), insertRect));
imageStamp.setRect(insertRect);

if (imagePath.endsWith("png")){
  BitmapFactory.Options tmpOptions = new BitmapFactory.Options();
  tmpOptions.inMutable = true;
  Bitmap bitmap = BitmapFactory.decodeFile(imagePath, tmpOptions);
  imageStamp.updateApWithBitmap(bitmap);
  bitmap.recycle();
}else {
  imageStamp.setImageStamp(imagePath);
  imageStamp.updateAp();
}
kotlin
// Retrieve the page object for creating annotations.
val pageNumber = 0
val page = document.pageAtIndex(pageNumber)

// Create a standard signature stamp.
val standardStamp = page.addAnnot(CPDFAnnotation.Type.STAMP) as CPDFStampAnnotation
standardStamp.setStandardStamp(CPDFStampAnnotation.StandardStamp.COMPLETED)
val pageSize = page.size
val insertRect = standardStamp.rect
insertRect.set(
  page.convertRectFromPage(false, pageSize.width(), pageSize.height(), insertRect)
)
val defaultWidth = 200F
val vertex = PointF(0f, 0F)
insertRect.set(
  vertex.x,
  vertex.y,
  vertex.x + defaultWidth,
  vertex.y + defaultWidth * kotlin.math.abs(insertRect.height() / insertRect.width())
)
standardStamp.rect = page.convertRectToPage(false, pageSize.width(), pageSize.height(), insertRect)
standardStamp.updateAp()

// Create a text signature stamp.
val textStamp = page.addAnnot(CPDFAnnotation.Type.STAMP) as CPDFStampAnnotation
textStamp.textStamp = CPDFStampAnnotation.TextStamp(
  "Hello world",
  "2022/01/01 12:00:00",
  CPDFStampAnnotation.TextStampShape.TEXTSTAMP_RIGHT_TRIANGLE.id,
  CPDFStampAnnotation.TextStampColor.TEXTSTAMP_GREEN.id
)
val textStampInsertRect = textStamp.rect
textStampInsertRect.set(
  page.convertRectFromPage(false, pageSize.width(), pageSize.height(), textStampInsertRect)
)
textStampInsertRect.set(
  vertex.x,
  vertex.y,
  vertex.x + defaultWidth,
  vertex.y + defaultWidth * kotlin.math.abs(textStampInsertRect.height() / textStampInsertRect.width())
)
textStamp.rect = page.convertRectToPage(false, pageSize.width(), pageSize.height(), textStampInsertRect)
textStamp.updateAp()

// Create an image stamp.
val imageStamp = page.addAnnot(CPDFAnnotation.Type.STAMP) as CPDFStampAnnotation
val imagePath = "imagePath"
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true
BitmapFactory.decodeFile(imagePath, options)
val imageStampInsertRect = RectF(
  vertex.x,
  vertex.y,
  vertex.x + defaultWidth,
  vertex.y + defaultWidth * options.outHeight / options.outWidth
)
imageStamp.rect = page.convertRectToPage(false, pageSize.width(), pageSize.height(), imageStampInsertRect)

if (imagePath.endsWith("png")) {
  val tmpOptions = BitmapFactory.Options()
  tmpOptions.inMutable = true
  val bitmap = BitmapFactory.decodeFile(imagePath, tmpOptions)
  imageStamp.updateApWithBitmap(bitmap)
  bitmap.recycle()
} else {
  imageStamp.setImageStamp(imagePath)
  imageStamp.updateAp()
}

ReaderView Synchronization

If the PDF is displayed via CPDFReaderView and the target page is loaded or visible, the annotation must be added to the corresponding CPDFPageView to be immediately visible.

java
CPDFPageView pageView = (CPDFPageView) readerView.getChild(pageIndex);
if (pageView != null) {
    boolean isFocused = false;
    pageView.addAnnotation(annotation, isFocused);
}
kotlin
val pageView = readerView.getChild(pageIndex) as? CPDFPageView
pageView?.let {
    val isFocused = false
    it.addAnnotation(annotation, isFocused)
}

Interactive Creation

This applies to user-added stamp annotations. Users can click anywhere on a PDF page to create a stamp annotation.

Workflow:

  1. Switch CPDFReaderView to annotation mode.
  2. Enable touch mode for adding stamp annotations.
  3. User clicks the page to add the stamp.
  4. Exit annotation mode.

Example:

java
// 1. Enter annotation mode
readerView.setViewMode(CPDFReaderView.ViewMode.ANNOT);

// 2. Enable stamp annotation mode
readerView.setTouchMode(CPDFReaderView.TouchMode.ADD_ANNOT);
readerView.setCurrentFocusedType(CPDFAnnotation.Type.STAMP);

// 3. Set the stamp attributes
CPDFAnnotAttribute attribute = readerView.getReaderAttribute().getAnnotAttribute();
CPDFStampAttr stampAttr = attribute.getStampAttr();
stampAttr.setStandardStamp(CPDFStampAnnotation.StandardStamp.ACCEPTED);
stampAttr.setTextStamp(params.getTextStamp());
stampAttr.setImagePath(params.getImagePath(), false);

// 4. Exit annotation mode
readerView.setTouchMode(CPDFReaderView.TouchMode.BROWSE);
readerView.setCurrentFocusedType(CPDFAnnotation.Type.UNKNOWN);
kotlin
readerView.setViewMode(CPDFReaderView.ViewMode.ANNOT)
readerView.setTouchMode(CPDFReaderView.TouchMode.ADD_ANNOT)
readerView.setCurrentFocusedType(CPDFAnnotation.Type.STAMP)

val attribute = readerView.getReaderAttribute().getAnnotAttribute()
val stampAttr = attribute.getStampAttr()
stampAttr.setStandardStamp(CPDFStampAnnotation.StandardStamp.ACCEPTED)
stampAttr.setTextStamp(params.getTextStamp())
stampAttr.setImagePath(params.getImagePath(), false)

readerView.setTouchMode(CPDFReaderView.TouchMode.BROWSE)
readerView.setCurrentFocusedType(CPDFAnnotation.Type.UNKNOWN)

Create Ink Annotations

Ink annotations provide a direct and convenient method for drawing annotations.

Programmatic Creation

The steps to create a ink annotation are as follows:

  1. Obtain the page object where the annotation needs to be created.

  2. Create a ink annotation on that page.

  3. Set the path taken by the ink annotation.

  4. Set other properties of the annotation.

  5. Update the annotation appearance to display it on the document.

This example shows how to create ink annotations:

java
// Retrieve the page object for creating annotations.
int pageNumber = 0;
CPDFPage page = document.pageAtIndex(pageNumber);
// Set the path traced by the freehand annotation.
ArrayList<ArrayList<PointF>> mDrawing = new ArrayList<>();
ArrayList<PointF> arc1 = new ArrayList<>();
arc1.add(new PointF(0,0));
arc1.add(new PointF(10,10));
arc1.add(new PointF(20,20));
mDrawing.add(arc1);
ArrayList<PointF> arc2 = new ArrayList<>();
arc2.add(new PointF(5,5));
arc2.add(new PointF(15,15));
arc2.add(new PointF(25,25));
mDrawing.add(arc2);
// Create a ink annotation on the page.
CPDFInkAnnotation inkAnnotation = (CPDFInkAnnotation) page.addAnnot(CPDFInkAnnotation.Type.INK);
float scaleValue = 1;
inkAnnotation.setColor(Color.BLUE);
inkAnnotation.setAlpha(255);
inkAnnotation.setBorderWidth(10 / scaleValue);
RectF rect = null;
RectF size = page.getSize();
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 minimum bounding rectangle for the path ******/
    if (rect == null) {
      rect = new RectF(point.x, point.y, point.x, point.y);
    } else {
      rect.union(point.x, point.y);
    }
    /****** Calculate the coordinates transformed to the page and stored in the linePath collection ******/
    linePath[pointIndex] = (page.convertPointToPage(false, size.width(), size.height(), point));
  }
  path[lineIndex] = linePath;
}
float dx = 10 / scaleValue / 2;
rect.inset(-dx, -dx);
rect.set(page.convertRectToPage(false, size.width(), size.height(), rect));
inkAnnotation.setInkPath(path);
inkAnnotation.setRect(rect);
inkAnnotation.updateAp();
kotlin
// Retrieve the page object for creating annotations.
val pageNumber = 0
val page = document.pageAtIndex(pageNumber)
// Set the path traced by the freehand annotation.
val mDrawing = mutableListOf<MutableList<PointF>>()
val arc1 = mutableListOf(PointF(0f, 0f), PointF(10f, 10f), PointF(20f, 20f))
mDrawing.add(arc1)
val arc2 = mutableListOf(PointF(5f, 5f), PointF(15f, 15f), PointF(25f, 25f))
mDrawing.add(arc2)
// Create a ink annotation on the page.
val inkAnnotation = page.addAnnot(CPDFAnnotation.Type.INK) as CPDFInkAnnotation
val scaleValue = 1
inkAnnotation.color = Color.BLUE
inkAnnotation.alpha = 255
inkAnnotation.borderWidth = 10F / scaleValue

var rect: RectF? = null
val size = page.size
if (size.isEmpty) {
  return
}
val lineCount = mDrawing.size
val path = Array(lineCount) { emptyArray<PointF>() }
for (lineIndex in 0 until lineCount) {
  val line = mDrawing[lineIndex]
  val pointCount = line.size
  val linePath = Array(pointCount) { PointF() }
  for (pointIndex in 0 until pointCount) {
    val point = line[pointIndex]
    /****** Calculate the minimum bounding rectangle for the path ******/
    if (rect == null) {
      rect = RectF(point.x, point.y, point.x, point.y)
    } else {
      rect.union(point.x, point.y)
    }
    /****** Calculate the coordinates transformed to the page and stored in the linePath collection ******/
    linePath[pointIndex] = page.convertPointToPage(
      false,
      size.width(),
      size.height(),
      point
    )
  }
  path[lineIndex] = linePath
}
val dx = 10F / scaleValue / 2
rect?.inset(-dx, -dx)
rect?.set(page.convertRectToPage(false, size.width(), size.height(), rect))
inkAnnotation.inkPath = path
inkAnnotation.rect = rect
inkAnnotation.updateAp()

ReaderView Synchronization

If the PDF is displayed via CPDFReaderView and the target page is loaded or visible, add the annotation to CPDFPageView:

java
CPDFPageView pageView = (CPDFPageView) readerView.getChild(pageIndex);
if (pageView != null) {
    boolean isFocused = false;
    pageView.addAnnotation(annotation, isFocused);
}
kotlin
val pageView = readerView.getChild(pageIndex) as? CPDFPageView
pageView?.let { it.addAnnotation(annotation, false) }

Interactive Creation

Users can draw freely on the PDF page to create ink annotations.

Workflow:

  1. Switch CPDFReaderView to annotation mode.
  2. Enable touch mode for ink annotations.
  3. User draws on the page.
  4. Exit annotation mode.

Example:

java
readerView.setViewMode(CPDFReaderView.ViewMode.ANNOT);
readerView.setTouchMode(CPDFReaderView.TouchMode.ADD_ANNOT);
readerView.setCurrentFocusedType(Type.INK);

// Exit annotation mode
readerView.setTouchMode(CPDFReaderView.TouchMode.BROWSE);
readerView.setCurrentFocusedType(CPDFAnnotation.Type.UNKNOWN);
kotlin
readerView.setViewMode(CPDFReaderView.ViewMode.ANNOT)
readerView.setTouchMode(CPDFReaderView.TouchMode.ADD_ANNOT)
readerView.setCurrentFocusedType(Type.INK)

// Exit annotation mode
readerView.setTouchMode(CPDFReaderView.TouchMode.BROWSE)
readerView.setCurrentFocusedType(CPDFAnnotation.Type.UNKNOWN)

Helper API for Ink Drawing

java
CPDFReaderView.TInkDrawHelper inkDrawHelper = readerView.getInkDrawHelper();
inkDrawHelper.setMode(IInkDrawCallback.Mode.ERASE); // Set eraser mode
inkDrawHelper.setMode(IInkDrawCallback.Mode.DRAW);  // Set draw mode
inkDrawHelper.clearInkOperation();                  // Clear all strokes
boolean canRedo = inkDrawHelper.canRedo();
boolean canUndo = inkDrawHelper.canUndo();
inkDrawHelper.onSave();   // Save current strokes
inkDrawHelper.onUndo();   // Undo last stroke
inkDrawHelper.onRedo();   // Redo undone stroke
kotlin
val inkDrawHelper = readerView.inkDrawHelper
inkDrawHelper.setMode(IInkDrawCallback.Mode.ERASE)
inkDrawHelper.setMode(IInkDrawCallback.Mode.DRAW)
inkDrawHelper.clearInkOperation()
val canRedo = inkDrawHelper.canRedo()
val canUndo = inkDrawHelper.canUndo()
inkDrawHelper.onSave()
inkDrawHelper.onUndo()
inkDrawHelper.onRedo()

Create Audio Annotations

Programmatic Creation

The steps to create an audio annotation are as follows:

  1. Obtain the page object where the annotation needs to be created.

  2. Create an audio annotation on that page.

  3. Set the audio file.

  4. Set other properties.

  5. Update the annotation appearance to display it on the document.

This example shows how to create audio annotations:

java
// Retrieve the page object for creating annotations.
CPDFPage page = document.pageAtIndex(0);
CPDFSoundAnnotation soundAnnotation = (CPDFSoundAnnotation) page.addAnnot(CPDFAnnotation.Type.SOUND);
RectF insertRect = new RectF(50, 300, 100, 350);
RectF size = page.getSize();
insertRect =  page.convertRectToPage(false, size.width(), size.height(), insertRect);
soundAnnotation.setRect(insertRect);
soundAnnotation.setSoundPath(FileUtils.getAssetsTempFile(SampleApplication.getInstance(), "Bird.wav"));
soundAnnotation.updateAp();
kotlin
val page = document.pageAtIndex(0)
val soundAnnotation = page.addAnnot(CPDFAnnotation.Type.SOUND) as CPDFSoundAnnotation
var insertRect = RectF(50F, 300F, 100F, 350F)

val size = page.size
insertRect = page.convertRectToPage(false, size.width(), size.height(), insertRect)

soundAnnotation.rect = insertRect
soundAnnotation.setSoundPath(getAssetsTempFile(context(), "Bird.wav"))
soundAnnotation.updateAp()

ReaderView Synchronization

java
CPDFPageView pageView = (CPDFPageView) readerView.getChild(pageIndex);
if (pageView != null) {
    boolean isFocused = false;
    pageView.addAnnotation(annotation, isFocused);
}
kotlin
val pageView = readerView.getChild(pageIndex) as? CPDFPageView
pageView?.let { it.addAnnotation(annotation, false) }

Interactive Creation

Users can click on the PDF page to add audio annotations.

Workflow:

  1. Switch CPDFReaderView to annotation mode.
  2. Enable touch mode for audio annotations.
  3. User clicks on the page.
  4. Exit annotation mode.

Example:

java
readerView.setViewMode(CPDFReaderView.ViewMode.ANNOT);
readerView.setTouchMode(CPDFReaderView.TouchMode.ADD_ANNOT);
readerView.setCurrentFocusedType(Type.SOUND);

readerView.setTouchMode(CPDFReaderView.TouchMode.BROWSE);
readerView.setCurrentFocusedType(CPDFAnnotation.Type.UNKNOWN);
kotlin
readerView.setViewMode(CPDFReaderView.ViewMode.ANNOT)
readerView.setTouchMode(CPDFReaderView.TouchMode.ADD_ANNOT)
readerView.setCurrentFocusedType(Type.SOUND)

readerView.setTouchMode(CPDFReaderView.TouchMode.BROWSE)
readerView.setCurrentFocusedType(CPDFAnnotation.Type.UNKNOWN)