Position and Size

This article is about handling annotation rects correctly, i.e. reading, modifying and writing them. If you are interested in the different coordinate systems of PSPDFKit and PDFs, have a look at our coordinate conversion guide instead.

Bounding box

Each annotation has a size and a position, called the annotation's "bounding box". To access the bounding box simply call Annotation#getBoundingBox which will return a RectF instance, holding the annotation's size and position in PDF coordinates.

Copy
1
2
3
4
5
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.")
Copy
1
2
3
4
5
6
7
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.

Copy
1
2
3
4
5
6
7
8
9
// IMPORTANT: Create a copy of the bounding box, as direct modification
// of the returned instance will lead to an inconsistent annotation state.
val boundingBox = RectF(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")
Copy
1
2
3
4
5
6
7
8
9
// IMPORTANT: Create a copy of the bounding box, as direct modification
// of the returned instance will lead to an inconsistent annotation state.
final RectF boundingBox = new RectF(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());

Warning: Don’t modify the RectF returned by Annotation#getBoundingBox if you want to alter the position or size of the annotation. A returned RectF is a copy of the annotation’s bounding box. See the next section on correctly altering the bounding box.

Changing the bounding box

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

Copy
1
2
3
4
5
6
7
8
9
10
11
// Unlike in the previous example the bounding box is not copied, but reused.
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)
Copy
1
2
3
4
5
6
7
8
9
10
11
// Unlike in the previous example the bounding box is not copied, but reused.
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 will not be applied, meaning the they can't be rendered or saved back to the document.