Adding shape annotations to PDFs programmatically enables teams to automate visual markup, build diagram creation tools, and implement technical drawing workflows. Whether you’re creating architectural markups, highlighting important document regions, building callout systems for technical documentation, implementing diagram annotation tools, or creating visual review workflows, shape annotations provide precise geometric control. Shape annotations include lines with customizable endings (arrows, circles, diamonds), circles (ellipses) for highlighting regions, and squares (rectangles) for boundary marking, all with configurable colors and border widths.

How Nutrient helps you achieve this

Nutrient Java SDK handles PDF shape annotation structures and geometric rendering. With the SDK, you don’t need to worry about:

  • 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

Instead, Nutrient provides an API that handles all the complexity behind the scenes, letting you focus on your business logic.

Complete implementation

Below is a complete working example that demonstrates adding various shape annotations to a PDF. The following lines set up the Java application. The package declaration and import statements bring in all necessary classes from the Nutrient SDK:

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 {

The main method defines the entry point that will contain the shape annotation creation logic:

public static void main(String[] args) {

The Document.open() call opens the PDF document. The try-with-resources statement ensures the document is automatically closed when you’re done, preventing resource leaks. The following code creates a PDF editor, accesses the page collection, ensures at least one page exists by adding a letter-size page (612×792 points) if the document is empty, and retrieves the annotation collection from the first page:

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

The following code adds a horizontal line annotation from coordinates (50, 700) to (200, 700), creating a 150-point wide line at a fixed y-position. The addLine() method takes four coordinate parameters (startX, startY, endX, endY), plus author and contents metadata. Lines are created with default black color and 1-point border width, making them suitable for simple underlines, dividers, or connection indicators in technical documentation:

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

The following code creates a diagonal line from (50, 650) to (200, 600), descending 50 points over 150 horizontal points. After creation, the line is customized using property methods: setEndCap() applies a closed arrowhead to the end point, setColor() sets the line to blue (ARGB: 255, 0, 0, 255), and setBorderWidth() increases the stroke width to 2 points for better visibility. Line annotations with arrow endings are commonly used for callouts, pointing to specific document regions, or creating directional indicators in technical diagrams:

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);

The PdfLineEndingStyle enumeration provides nine ending styles for line annotations. None creates plain lines without endings. Geometric endings include Square (rectangular cap), Circle (circular cap), and Diamond (diamond shape). Arrow styles include OpenArrow (outline arrowhead), ClosedArrow (filled arrowhead), ReverseOpenArrow, and ReverseClosedArrow for reverse direction indicators. Butt creates a perpendicular line ending, and Slash adds a diagonal slash mark. Both start and end points can have independent ending styles using setStartCap() and setEndCap().

Adding a circle annotation

The following code adds a circle annotation at coordinates (250, 550) with dimensions 100×100 points, creating a perfect circle. The addCircle() method takes position (x, y) and size (width, height) parameters — when width equals height, a perfect circle renders; otherwise, an ellipse stretches to fit the bounding box. Circles are created with default black stroke and 1-point border width. After creation, setColor() changes the border to green (ARGB: 255, 0, 128, 0) and setBorderWidth() increases the stroke to 2 points. Circle annotations are commonly used for highlighting regions of interest, marking problem areas in technical reviews, or creating visual emphasis in diagrams:

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

The following code adds a square (rectangle) annotation at coordinates (400, 550) with dimensions 150×100 points, creating a rectangular boundary. The addSquare() method uses the same parameter structure as addCircle() but renders rectangles regardless of aspect ratio—equal width and height produces a perfect square, while differing dimensions create rectangles. After creation, setColor() sets the border to purple (ARGB: 255, 128, 0, 128) and setBorderWidth() increases the stroke to 2 points. Square annotations are commonly used for marking document sections requiring review, creating boundary boxes around important content, or defining rectangular regions in architectural or engineering drawings:

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

The following code demonstrates creating a unified visual markup system by combining multiple shape annotations with consistent styling. The first shape creates a callout line from (50, 500) to (150, 450) with an open arrow ending, pointing to the target region. The second shape adds an elliptical highlight (100×60 points) at the arrow’s endpoint to emphasize the area of interest. The third shape adds a rectangular selection box (100×60 points) adjacent to the circle, defining a specific section boundary. All three shapes use matching orange color (ARGB: 255, 255, 165, 0) and 1.5-point border width to create a cohesive visual indicator. This pattern is commonly used for creating callout annotations in technical documentation, architectural markups, or collaborative review systems where multiple shapes work together to convey a single annotation message:

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);

The final code block saves the document with all shape annotations and closes the editor:

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

Conclusion

The shape annotation workflow consists of several key operations:

  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.

Nutrient handles shape annotation dictionary structures, geometric path construction, stroke and fill operations, and appearance stream generation so you don’t need to understand PDF drawing operators or manage coordinate transformation matrices manually. The shape annotation system provides precise geometric control over lines, circles, and rectangles, enabling visual markup for technical documentation, architectural drawings, diagram creation, and collaborative review workflows.