Retrieve or Set the Annotation Bounding Box in Android

When working with PDF annotations, you’ll quickly come across a property called the bounding box. This article provides an overview of bounding boxes and their corresponding rects.

A bounding box is the rectangular area that surrounds an annotation. It’s represented by four attributes that are used to calculate the rectangle’s position and size in PDF page coordinates.

Accessing the Bounding Box

Each annotation has a size and a position, known as the annotation’s bounding box. To access the bounding box, call Annotation#getBoundingBox. This will return a RectF instance, which holds the annotation’s size and position in PDF coordinates:

Log.d(TAG, "The annotation sits at coordinates [${annotation.boundingBox.left}, " +
    "${annotation.boundingBox.bottom}].")

Log.d(TAG, "The annotation is " +
    "${annotation.boundingBox.width()} x ${annotation.boundingBox.height()} PDF points large.")
final RectF boundingBox = annotation.getBoundingBox();

Log.d(TAG, String.format("The annotation sits at coordinates [%f, %f].",
    boundingBox.left, boundingBox.bottom));

Log.d(TAG, String.format("The annotation is %f x %f PDF points large.",
    boundingBox.width(), boundingBox.height()));

Calculating Screen Coordinates

The bounding box returned by Annotation#getBoundingBox is in the PDF coordinate space. If your app needs screen coordinates, convert the bounding box using the coordinate conversion API:

// Retrieve a copy of the annotation's current bounding box.
val boundingBox = annotation.boundingBox

// After conversion, the `boundingBox` will be in screen coordinates.
fragment.convertPdfRectToViewRect(boundingBox, annotation.pageIndex)

Log.d(TAG, "The annotation's screen size is " +
    " ${boundingBox.width().toInt()} x ${boundingBox.height().toInt()} pixels")
// Retrieve a copy of the annotation's current bounding box.
final RectF boundingBox = annotation.getBoundingBox();

// After conversion, the `boundingBox` will be in screen coordinates.
fragment.convertPdfRectToViewRect(boundingBox, annotation.getPageIndex());

Log.d(TAG, String.format("The annotation's screen size is %d x %d pixels",
    (int) boundingBox.width(), (int) boundingBox.height());

ℹ️ Note: Since Annotation#getBoundingBox returns a copy of the annotation’s bounding box, you have to call [Annotation$setBoundingBox][] again if you want to modify its value. See the next section for more information on correctly altering the bounding box.

Changing the Bounding Box

To change the annotation’s bounding box, call Annotation#setBoundingBox and provide a RectF instance holding the desired size and position (in PDF coordinates). You can safely reuse the existing bounding box instance in this situation:

// Retrieve the current bounding box from the annotation.
val boundingBox = annotation.boundingBox

// Move the bounding box 100 points up.
boundingBox.offset(0, -100)

// Write the new position back to the annotation.
annotation.boundingBox = boundingBox

// Make the changes visible on the screen.
fragment.notifyAnnotationHasChanged(annotation)
// Retrieve the current bounding box from the annotation.
final RectF boundingBox = annotation.getBoundingBox();

// Move the bounding box 100 points up.
boundingBox.offset(0, -100);

// Write the new position back to the annotation.
annotation.setBoundingBox(boundingBox);

// Make the changes visible on the screen.
fragment.notifyAnnotationHasChanged(annotation);

❗Important: If you forget to call Annotation#setBoundingBox, your changes to the bounding box won’t be applied, meaning they can’t be rendered or saved back to the document.