Use shape annotations to add structured visual markup to PDF documents.

Common use cases include:

  • Architectural and technical markups
  • Diagram annotation workflows
  • Region highlighting and boundary marking
  • Collaborative review callouts

In this guide, you’ll add:

  • Lines with configurable ending styles
  • Circles and ellipses
  • Squares and rectangles
  • Custom colors and border widths
Download sample

How Nutrient helps

Nutrient Java SDK handles shape annotation structures and rendering.

The SDK handles:

  • Parsing shape annotation dictionaries and path construction
  • Managing stroke and fill operations with appearance streams
  • Handling geometric calculations and coordinate transformations
  • Complex line ending styles and cap rendering

Complete implementation

This example adds multiple shape annotations to a PDF:

package io.nutrient.Sample;
import io.nutrient.sdk.Document;
import io.nutrient.sdk.types.Color;
import io.nutrient.sdk.editors.PdfEditor;
import io.nutrient.sdk.editors.pdf.pages.PdfPageCollection;
import io.nutrient.sdk.editors.pdf.pages.PdfPage;
import io.nutrient.sdk.editors.pdf.annotations.PdfAnnotationCollection;
import io.nutrient.sdk.editors.pdf.annotations.PdfLineAnnotation;
import io.nutrient.sdk.editors.pdf.annotations.PdfCircleAnnotation;
import io.nutrient.sdk.editors.pdf.annotations.PdfSquareAnnotation;
import io.nutrient.sdk.enums.PdfLineEndingStyle;
public class ShapeAnnotations {

Create the main method as the sample entry point:

public static void main(String[] args) {

Open the document in try-with-resources, create an editor, and ensure one page exists:

try (Document document = Document.open("input.pdf")) {
PdfEditor editor = PdfEditor.edit(document);
PdfPageCollection pages = editor.getPageCollection();
if (pages.getCount() == 0) {
pages.add(612.0f, 792.0f);
}
PdfPage page = pages.getFirst();
PdfAnnotationCollection annotations = page.getAnnotationCollection();

Adding a line annotation

Add a line with addLine(startX, startY, endX, endY, author, contents).

In this sample:

  • The line runs from (50, 700) to (200, 700).
  • The default style is black with 1.0 border width.
PdfLineAnnotation line = annotations.addLine(
50.0f, 700.0f, 200.0f, 700.0f, // startX, startY, endX, endY
"Author",
"Simple horizontal line"
);

Adding a line with arrow endings

Create another line and customize its style.

In this sample:

  • The line runs from (50, 650) to (200, 600).
  • setEndCap(PdfLineEndingStyle.ClosedArrow) adds an arrowhead.
  • setColor(...) sets a blue stroke color.
  • setBorderWidth(2.0f) increases visibility.
PdfLineAnnotation arrow = annotations.addLine(
50.0f, 650.0f, 200.0f, 600.0f, // startX, startY, endX, endY
"Reviewer",
"Arrow pointing to important area"
);
// Optionally customize the line
arrow.setEndCap(PdfLineEndingStyle.ClosedArrow);
arrow.setColor(Color.fromArgb(255, 0, 0, 255));
arrow.setBorderWidth(2.0f);

PdfLineEndingStyle includes None, Square, Circle, Diamond, OpenArrow, ClosedArrow, ReverseOpenArrow, ReverseClosedArrow, Butt, and Slash.

Set start and end caps independently with setStartCap() and setEndCap().

Adding a circle annotation

Add a circle with addCircle(x, y, width, height, author, contents).

In this sample:

  • The bounds are x=250, y=550, width=100, and height=100.
  • Equal width and height create a circle.
  • Different values create an ellipse.
  • The style is updated to green with a 2.0f border width.
PdfCircleAnnotation circle = annotations.addCircle(
250.0f, 550.0f, 100.0f, 100.0f, // x, y, width, height
"Editor",
"Area of interest"
);
// Optionally customize the appearance
circle.setColor(Color.fromArgb(255, 0, 128, 0));
circle.setBorderWidth(2.0f);

Adding a square annotation

Add a square or rectangle with addSquare(x, y, width, height, author, contents).

In this sample:

  • The bounds are x=400, y=550, width=150, and height=100.
  • Equal width and height create a square.
  • Different values create a rectangle.
  • The style is updated to purple with a 2.0f border width.
PdfSquareAnnotation square = annotations.addSquare(
400.0f, 550.0f, 150.0f, 100.0f, // x, y, width, height
"Reviewer",
"Section to review"
);
// Optionally customize the appearance
square.setColor(Color.fromArgb(255, 128, 0, 128));
square.setBorderWidth(2.0f);

Combining multiple shapes

Use consistent styling across multiple shapes to build one callout set.

This sample creates:

  • A callout line with an open arrow
  • An ellipse highlight
  • A rectangular selection box

All shapes use the color orange and a 1.5f border width:

PdfLineAnnotation calloutLine = annotations.addLine(
50.0f, 500.0f, 150.0f, 450.0f, // startX, startY, endX, endY
"Author", "Callout line"
);
calloutLine.setEndCap(PdfLineEndingStyle.OpenArrow);
calloutLine.setColor(Color.fromArgb(255, 255, 165, 0));
calloutLine.setBorderWidth(1.5f);
PdfCircleAnnotation highlightCircle = annotations.addCircle(
150.0f, 420.0f, 100.0f, 60.0f, // x, y, width, height
"Author", "Highlighted area"
);
highlightCircle.setColor(Color.fromArgb(255, 255, 165, 0));
highlightCircle.setBorderWidth(1.5f);
PdfSquareAnnotation selectionBox = annotations.addSquare(
260.0f, 420.0f, 100.0f, 60.0f, // x, y, width, height
"Author", "Selection box"
);
selectionBox.setColor(Color.fromArgb(255, 255, 165, 0));
selectionBox.setBorderWidth(1.5f);

Save the output PDF and close the editor:

editor.saveAs("output.pdf");
editor.close();
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
}

Conclusion

Use this workflow to add shape annotations:

  1. Open the document and create an editor.
  2. Access the page collection and ensure at least one page exists.
  3. Retrieve the annotation collection for the target page.
  4. Add line annotations with start and end coordinates for connections or dividers.
  5. Customize lines with arrow endings using setEndCap() and PdfLineEndingStyle enumeration.
  6. Add circle annotations with position and dimensions for highlighting regions.
  7. Add square annotations with position and dimensions for boundary marking.
  8. Customize shape appearance using setColor() and setBorderWidth() methods.
  9. Combine multiple shapes with consistent styling for unified visual markup systems.
  10. Save and close the editor.

For related annotation workflows, refer to the Java SDK guides.