Click or drag to resize

Get access, create and manipulate annotations

This topic contains the following sections:

Overview

An annotation associates an object such as a line, note, highlight, or sound with a location on a page of a PDF document, as well as provides a way to interact with the user by means of the mouse and keyboard. Pdfium.Net SDK supports a wide variety of standard annotation types described in Table below.

Annotation Type

Description

Markup

Supported by SDK

Pdf3DAnnotation

3D annotation

No

No

PdfCaretAnnotation

Caret annotation

Yes

Yes

PdfCircleAnnotation

Circle annotation

Yes

Yes

PdfFileAttachmentAnnotation

File attachment annotation

Yes

Yes

PdfFreeTextAnnotation

Free text annotation

Yes

Yes

PdfHighlightAnnotation

Highlight annotation

Yes

Yes

PdfInkAnnotation

Ink annotation

Yes

Yes

PdfLineAnnotation

Line annotation

Yes

Yes

PdfLinkAnnotation

Link annotation

No

Yes

PdfMovieAnnotation

Movie annotation

No

No

PdfPolygonAnnotation

Polygon annotation

Yes

Yes

PdfPolylineAnnotation

Polyline annotation

Yes

Yes

PdfPopupAnnotation

Pop-up annotation

No

Yes

PdfPrinterMarkAnnotation

Printer’s mark annotation

No

No

PdfScreenAnnotation

Screen annotation

No

No

PdfSoundAnnotation

Sound annotation

Yes

Yes

PdfSquareAnnotation

Square annotation

Yes

Yes

PdfSquigglyAnnotation

Squiggly-underline annotation

Yes

Yes

PdfStampAnnotation

Rubber stamp annotation

Yes

Yes

PdfStrikeoutAnnotation

Strikeout annotation

Yes

Yes

PdfTextAnnotation

Text annotation

Yes

Yes

PdfTrapNetAnnotation

Trap network annotation

No

No

PdfUnderlineAnnotation

Underline annotation

Yes

Yes

PdfWatermarkAnnotation

Watermark annotation

No

Yes

PdfWidgetAnnotation

Widget annotation

No

No

Note Note

Lack of support does not mean that these annotations are not available at all. You can create, access and manipulate such annotations using dictionaries in accordance with the PDF specification.

The annotation classes are contained in the Patagames.Pdf.Net.Annotations namespace and are grouped into a tree structure

Open in full size

Annotations

Markup Annotations

Many annotation types are defined as markup annotations because they are used primarily to mark up PDF documents. These annotations have text that appears as part of the annotation and may be displayed in other ways by a viewer application, such as in a Comments pane.

Markup annotations are divided into the following groups:

  • Free text annotations display text directly on the page. The annotation’s Contents property specifies the displayed text.

  • Most other markup annotations have an associated pop-up window that may contain text. The annotation’s Contents property specifies the text to be displayed when the pop-up window is opened. These include text, line, square, circle, polygon, polyline, highlight, underline, squiggly-underline, strikeout, rubber stamp, caret, ink, and file attachment annotations.

  • Sound annotations do not have a pop-up window but may also have associated text specified by the Contents property.

The remaining annotation types are not considered markup annotations:

  • The pop-up annotation type typically does not appear by itself; it is associated with a markup annotation that uses it to display text. The Contents property for a pop-up annotation is relevant only if it has no PdfPopupAnnotationParent; in that case, it represents the text of the annotation.

  • For all other annotation types (Link, Movie, Widget, PrinterMark, and TrapNet), the Contents property provides an alternate representation of the annotation’s contents in human-readable form, which is useful when extracting the document’s contents in support of accessibility to users with disabilities or for other purposes.

Accessing Annotations

The following code snippets provides a quick example on how to retrieve annotations using the PdfPageAnnots property.

Used namespaces

C#
using Patagames.Pdf;
using Patagames.Pdf.Enums;
using Patagames.Pdf.Net;
using Patagames.Pdf.Net.Annotations;
using Patagames.Pdf.Net.BasicTypes;
using Patagames.Pdf.Net.Wrappers;

How to access the collection of annotations

C#
public void AccessingAnnotations(PdfPage page)
{
    PdfAnnotationCollection annots = page.Annots;
    if (annots == null)
        return; //There are no annotations on the page.
}

If there are no annotations on the page, then the annots is null. If you want to add annotation, you must create an empty annotation collection before moving on. Please refer Creating an annotation for details.

Iterating through the annotation collection

C#
foreach (var annotation in page.Annots)
{
    if (annotation is PdfTextAnnotation)
    {
        var textAnnotation = annotation as PdfTextAnnotation;
        //Process text annotation
        //...
    }
    else if (annotation is PdfSoundAnnotation)
    {
        var soundAnnotation = annotation as PdfSoundAnnotation;
        //Process sound annotation
        //...
    }
    //... 
    //and so on
}
Creating an Annotation

Create an empty annotation collection

If there are no annotations on the page, the PdfPageAnnots array is null. In this case you must create empty annotation collection using the PdfPageCreateAnnotations method.

C#
if (page.Annots == null)
    page.CreateAnnotations(); //create an empty annotation collection

PdfAnnotationCollection annots = page.Annots;

Now annots is an empty PdfAnnotationCollection

Create annotations by setting up the annotation properties.

Annotation can be created using a PdfAnnotation(PdfPage) constructor that takes a single parameter - the page with which this annotation is associated.

After creating the annotation and setting up all the necessary properties, call the RegenerateAppearances method. This method will generate graphic objects based on the properties of the annotation and place them in the PdfAnnotationNormalAppearance collection. NormalAppearance enable the annotation to be presented visually on a page. NormalAppearance is also used for printing the annotation.

Note Note

The same is the case if you modify an existing annotation. After changing its properties, you need to call the RegenerateAppearances method.

Finally, the annotation needs to be added to the PdfPage.Annots array of the corresponding page.

C#
//Create a new text annotation
var annot = new PdfTextAnnotation(page);
annot.Rectangle = new FS_RECTF(50, 100, 70, 70);
annot.StandardIconName = IconNames.Note;
annot.Color = FS_COLOR.Yellow;
annot.Opacity = 0.5f;

//Appearance should be regenerated.
annot.RegenerateAppearances();

//Add annotation to the page
page.Annots.Add(annot);
Caution note Caution

An annotation may be referenced from the PdfPage.Annots array of only one page. Attempting to share an annotation among multiple pages, as well as adding an annotation associated with another page, produces unpredictable behavior.

Create annotations with specialized constructors.

Most annotations have several constructors that take as many parameters as needed to create the annotation on a single line of code. When using such a constructor, there is no need to call the RegenerateAppearances method. The PdfAnnotationNormalAppearance will be generated during construction.

For example:

C#
public void CreateTextAnnotationWithOneLineOfCode(PdfPage page)
{
    page.Annots.Add(new PdfTextAnnotation(page, IconNames.Comment, FS_COLOR.Yellow, "Comment", "Subject", 80.0f, 750.0f));
}

Custom annotation appearance

If you want to change the default appearance of annotation, you can create your own graphic objects and place them into the NormalAppearance collection. After that you must call GenerateAppearance method.

C#
public void CreateCustomIconTextAnnotation(PdfPage page)
{
    //Create text annotation
    var annot = new PdfTextAnnotation(page);
    annot.ExtendedIconName = "MyImage";
    annot.Contents = "text";
    annot.Subject = "subj";

    //Load bitmap from a file and create image object.
    var bmp = PdfBitmap.FromFile(@"logo_square.png");
    var img = PdfImageObject.Create(page.Document, bmp, 0, 0);

    //create an empty normal appearance of the annotation.
    annot.CreateEmptyAppearance(AppearanceStreamModes.Normal);
    //add the image to the NormalAppearance.
    annot.NormalAppearance.Add(img);
    //Generate the NormalAppearance
    annot.GenerateAppearance(AppearanceStreamModes.Normal);

    page.Annots.Add(annot);
}
Text Annotations

A text annotation represents a “sticky note” attached to a point in the PDF document. When closed, the annotation appears as an icon; when open, it displays a pop-up window containing the text of the note in a font and size chosen by the viewer application.

Create the text annotations by passing parameters to the specialized constructor

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    page.Annots.Add(new PdfTextAnnotation(page, IconNames.Note, "Note", "Subject", 50.0f, 750.0f));
    page.Annots.Add(new PdfTextAnnotation(page, IconNames.Comment, FS_COLOR.Yellow, "Comment", "Subject", 80.0f, 750.0f));
    page.Annots.Add(new PdfTextAnnotation(page, IconNames.Key, "Key", "Subject", 110.0f, 750.0f));
    page.Annots.Add(new PdfTextAnnotation(page, IconNames.Help, "Help", "Subject", 140.0f, 750.0f));
    page.Annots.Add(new PdfTextAnnotation(page, IconNames.NewParagraph, "New Paragraph", "Subject", 170.0f, 750.0f));
    page.Annots.Add(new PdfTextAnnotation(page, IconNames.Paragraph, "Paragrapth", "Subject", 200.0f, 750.0f));
    page.Annots.Add(new PdfTextAnnotation(page, IconNames.Insert, "Insert", "Subject", 230.0f, 750.0f));
    page.Annots.Add(new PdfTextAnnotation(page, IconNames.Extended, "Star", "Subject", 260.0f, 750.0f));

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}

Create text annotation by setting up the annotation properties

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    var annot = new PdfTextAnnotation(page);
    annot.Color = FS_COLOR.Red;
    annot.Contents = "This is a contents";
    annot.Opacity = 0.6f;
    annot.Subject = "This is a subj";
    annot.Text = "This is a user";
    annot.Rectangle = new FS_RECTF(50, 730, 70, 710);
    annot.StandardIconName = IconNames.Note;

    //Appearance should be regenerated.
    annot.RegenerateAppearances();

    page.Annots.Add(annot);

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}

text annot sample

A link annotation represents either a hypertext link to a destination elsewhere in the document or an action to be performed.

How to create link annotation that links to another page in the same PDF

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    //Add a text object to the page.
    var textObject = PdfTextObject.Create("Click me to navigate to 2nd page", 0, 0, PdfFont.CreateStock(page.Document, FontStockNames.Arial), 14);
    textObject.Location = new FS_POINTF(50, page.Height - textObject.BoundingBox.Height - 50);
    page.PageObjects.Add(textObject);
    page.GenerateContent();

    // Create link annotation around the text object 
    var annot = new PdfLinkAnnotation(page);
    var bbox = textObject.BoundingBox;
    bbox.Inflate(new FS_RECTF(10, 10, 10, 10));
    annot.Rectangle = bbox;
    int pageIndex = 1;
    annot.Link.Destination = PdfDestination.CreateXYZ(page.Document, pageIndex);
    annot.Link.QuadPoints.Add(new FS_QUADPOINTSF(bbox));

    page.Annots.Add(annot);

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}
link annot sample 01

How to create link annotation that links to web site

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    //Add a text object to the page.
    var textObject = PdfTextObject.Create("Click me to navigate to url", 0, 0, PdfFont.CreateStock(page.Document, FontStockNames.Arial), 14);
    textObject.Location = new FS_POINTF(50, page.Height - textObject.BoundingBox.Height - 50);
    page.PageObjects.Add(textObject);
    page.GenerateContent();

    var bbox = textObject.BoundingBox;
    bbox.Inflate(new FS_RECTF(10, 10, 10, 10));

    // Create link annotation from dictionary
    var annotDict = PdfTypeDictionary.Create();
    annotDict["Type"] = PdfTypeName.Create("Annot");
    annotDict["Subtype"] = PdfTypeName.Create("Link");
    annotDict["A"] = PdfTypeDictionary.Create();
    annotDict["A"].As<PdfTypeDictionary>()["Type"] = PdfTypeName.Create("Action");
    annotDict["A"].As<PdfTypeDictionary>()["S"] = PdfTypeName.Create("URI");
    annotDict["A"].As<PdfTypeDictionary>()["URI"] = PdfTypeString.Create("https://pdfium.patagames.com");
    annotDict["Rect"] = bbox.ToArray();
    annotDict["QuadPoints"] = new FS_QUADPOINTSF(bbox).ToArray();

    var annot = new PdfLinkAnnotation(page, annotDict);
    page.Annots.Add(annot);

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}
link annot sample 02

How to create link annotation without border around it

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    //Add a text object to the page.
    var textObject = PdfTextObject.Create("Link annotation without border", 0, 0, PdfFont.CreateStock(page.Document, FontStockNames.Arial), 14);
    textObject.Location = new FS_POINTF(50, page.Height - textObject.BoundingBox.Height - 50);
    page.PageObjects.Add(textObject);
    page.GenerateContent();

    // Create link annotation around the text object 
    var annot = new PdfLinkAnnotation(page);
    var bbox = textObject.BoundingBox;
    bbox.Inflate(new FS_RECTF(10, 10, 10, 10));
    annot.Rectangle = bbox;
    int pageIndex = 1;
    annot.Link.Destination = PdfDestination.CreateXYZ(page.Document, pageIndex);
    annot.Link.QuadPoints.Add(new FS_QUADPOINTSF(bbox));
    annot.Dictionary["Border"] = PdfTypeArray.Create();
    annot.Dictionary["Border"].As<PdfTypeArray>().AddInteger(0);
    annot.Dictionary["Border"].As<PdfTypeArray>().AddInteger(0);
    annot.Dictionary["Border"].As<PdfTypeArray>().AddInteger(0);

    page.Annots.Add(annot);

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}
link annot sample 03
Line Annotations

A line annotation displays a single straight line on the page. The following figures show some aspects of line annotation.

Leader lines

Figure 8.5 Leader Lines

Lines with captions appearing as part of the line

Figure 8.6 Caption

Line with a caption appearing as part of the offset

Figure 8.7 Caption Offset

Line Ending Styles

Name

Appearance

Description

Square

linending 01

A square filled with the annotation’s interior color, if any

Circle

linending 02

A circle filled with the annotation’s interior color, if any

Diamond

linending 03

A diamond shape filled with the annotation’s interior color, if any

OpenArrow

linending 04

Two short lines meeting in an acute angle to form an open arrowhead

ClosedArrow

linending 05

Two short lines meeting in an acute angle as in the OpenArrow style (see above) and connected by a third line to form a triangular closed arrowhead filled with the annotation’s interior color, if any

None

linending 06

No line ending

Butt

linending 07

A short line at the endpoint perpendicular to the line itself

ROpenArrow

linending 08

Two short lines in the reverse direction from OpenArrow

RClosedArrow

linending 09

A triangular closed arrowhead in the reverse direction from ClosedArrow

Slash

linending 10

A short line at the endpoint approximately 30 degrees clockwise from perpendicular to the line itself

How to add a line annotation to an existing PDF document

The following code snippet provides a quick example on how to create line annotation.

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    var lineAnnotation = new PdfLineAnnotation(page);
    lineAnnotation.Color = FS_COLOR.Green;
    lineAnnotation.Contents = "Caption position: inline";
    lineAnnotation.CaptionPosition = CaptionPositions.Inline;
    lineAnnotation.Line = new PdfLinePointCollection<PdfLineAnnotation>();
    lineAnnotation.Line.Add(new FS_POINTF(50, 150));
    lineAnnotation.Line.Add(new FS_POINTF(page.Width - 150, page.Height - 50));
    lineAnnotation.LineStyle = new Patagames.Pdf.Net.Wrappers.PdfBorderStyle();
    lineAnnotation.LineStyle.Width = 3.0f;
    lineAnnotation.Cap = true;
    lineAnnotation.LineEnding = new PdfLineEndingCollection(LineEndingStyles.OpenArrow, LineEndingStyles.OpenArrow);
    lineAnnotation.InteriorColor = FS_COLOR.Red;
    lineAnnotation.CaptionOffset = new FS_SIZEF(0, 30);
    lineAnnotation.LeaderLineExtension = 20;
    lineAnnotation.LeaderLineLenght = -40;
    lineAnnotation.LeaderLineOffset = 50;

    //Appearance should be regenerated.
    lineAnnotation.RegenerateAppearances();

    page.Annots.Add(lineAnnotation);

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}

The above code will generate an annotation like the following image.

line annot sample
Polygon Annotations

Polygon annotations display closed polygons on the page. Such polygons may have any number of vertices connected by straight lines. The following code snippets provides a quick example on how to create polygon annotation.

Create a simple polygon annotation.

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    var annot = new PdfPolygonAnnotation(page);
    annot.Color = FS_COLOR.Green;
    annot.Opacity = 1f;
    annot.Vertices = new PdfLinePointCollection<PdfPolygonalChainAnnotation>();
    annot.Vertices.Add(new FS_POINTF(20, 280));
    annot.Vertices.Add(new FS_POINTF(300, 480));
    annot.Vertices.Add(new FS_POINTF(400, 150));
    annot.Vertices.Add(new FS_POINTF(350, 100));
    annot.LineStyle = new PdfBorderStyle();
    annot.LineStyle.Style = BorderStyles.Solid;
    annot.LineStyle.Width = 3;

    //Appearance should be regenerated.
    annot.RegenerateAppearances();

    page.Annots.Add(annot);

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}

The above code will generate an annotation like the following image.

polygon annot sample solid

Create polygon annotation with dash pattern

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();
    var annot = new PdfPolygonAnnotation(page);
    annot.Color = FS_COLOR.SteelBlue;
    annot.Opacity = 1f;
    annot.Vertices = new PdfLinePointCollection<PdfPolygonalChainAnnotation>();
    annot.Vertices.Add(new FS_POINTF(20, 280));
    annot.Vertices.Add(new FS_POINTF(300, 480));
    annot.Vertices.Add(new FS_POINTF(400, 150));
    annot.Vertices.Add(new FS_POINTF(350, 100));
    annot.LineStyle = new PdfBorderStyle();
    annot.LineStyle.Width = 3;
    annot.LineStyle.DashPattern = new float[] { 10, 5, 2, 5 };
    annot.LineStyle.Style = BorderStyles.Dashed;

    //Appearance should be regenerated.
    annot.RegenerateAppearances();

    page.Annots.Add(annot);

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}
polygon annot sample dashed

Create polygon annotation with a cloudy border effect

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    var annot = new PdfPolygonAnnotation(page);
    annot.Color = FS_COLOR.SteelBlue;
    annot.Opacity = 1f;
    annot.Vertices = new PdfLinePointCollection<PdfPolygonalChainAnnotation>();
    annot.Vertices.Add(new FS_POINTF(20, 280));
    annot.Vertices.Add(new FS_POINTF(300, 480));
    annot.Vertices.Add(new FS_POINTF(400, 150));
    annot.Vertices.Add(new FS_POINTF(350, 100));
    annot.BorderEffect = new PdfBorderEffect();
    annot.BorderEffect.Effect = BorderEffects.Cloudy;
    annot.BorderEffect.Intensity = 3;

    //Appearance should be regenerated.
    annot.RegenerateAppearances();

    page.Annots.Add(annot);

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}
polygon annot sample cloudy
Polyline Annotations

Polyline annotations are similar to polygons, except that the first and last vertex are not implicitly connected. Line ending styles can also be specified. The following code snippets provides a quick example on how to create polyline annotation.

Create a solid polyline annotation with specified line ending styles

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    var annot = new PdfPolylineAnnotation(page);
    annot.Color = FS_COLOR.Green;
    annot.Opacity = 1f;
    annot.Vertices = new PdfLinePointCollection<PdfPolygonalChainAnnotation>();
    annot.Vertices.Add(new FS_POINTF(20, 280));
    annot.Vertices.Add(new FS_POINTF(300, 480));
    annot.Vertices.Add(new FS_POINTF(400, 150));
    annot.Vertices.Add(new FS_POINTF(350, 100));
    annot.LineStyle = new PdfBorderStyle();
    annot.LineStyle.Style = BorderStyles.Solid;
    annot.LineStyle.Width = 7;
    annot.LineEnding = new PdfLineEndingCollection(LineEndingStyles.Diamond, LineEndingStyles.ROpenArrow);
    annot.InteriorColor = FS_COLOR.Red;

    //Appearance should be regenerated.
    annot.RegenerateAppearances();

    page.Annots.Add(annot);

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}
polyline annot sample solid
Square and Circle Annotations

Square and circle annotations display, respectively, a rectangle or an ellipse on the page. When opened, they display a pop-up window containing the text of the associated note. The rectangle or ellipse is inscribed within the annotation rectangle defined by the PdfAnnotationRectangle property.

Create a simple square annotation

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    FS_RECTF rect;
    var strokeColor = FS_COLOR.Black;
    var fillColor = FS_COLOR.SteelBlue;

    rect = new FS_RECTF(50, page.Height - 50, 150, page.Height - 150);
    page.Annots.Add(new PdfSquareAnnotation(page, rect, strokeColor, fillColor));

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}

Create the simple circle annotation

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    FS_RECTF rect;
    var strokeColor = FS_COLOR.Black;
    var fillColor = FS_COLOR.SteelBlue;

    rect = new FS_RECTF(175, page.Height - 50, 275, page.Height - 150);
    page.Annots.Add(new PdfCircleAnnotation(page, rect, strokeColor, fillColor));

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}

Create square annotation with dash pattern

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    var squareAnnot = new PdfSquareAnnotation(page);
    squareAnnot.Rectangle = new FS_RECTF(300, page.Height - 50, 400, page.Height - 150);
    squareAnnot.Color = FS_COLOR.Red;
    squareAnnot.InteriorColor = FS_COLOR.DarkGreen;
    squareAnnot.BorderStyle = new PdfBorderStyle();
    squareAnnot.BorderStyle.Style = BorderStyles.Dashed;
    squareAnnot.BorderStyle.Width = 3;
    squareAnnot.BorderStyle.DashPattern = new float[] { 10, 5, 2, 5 };

    //Appearance should be regenerated.
    squareAnnot.RegenerateAppearances();

    page.Annots.Add(squareAnnot);

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}

Create circle annotation with a cloudy border effect

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    var circleAnnot = new PdfCircleAnnotation(page);
    circleAnnot.Rectangle = new FS_RECTF(425, page.Height - 50, 525, page.Height - 150);
    circleAnnot.Color = FS_COLOR.Red;
    circleAnnot.InteriorColor = FS_COLOR.DarkGreen;
    circleAnnot.BorderStyle = new PdfBorderStyle();
    circleAnnot.BorderStyle.Style = BorderStyles.Solid;
    circleAnnot.BorderStyle.Width = 3;
    circleAnnot.BorderEffect = new PdfBorderEffect();
    circleAnnot.BorderEffect.Effect = BorderEffects.Cloudy;
    circleAnnot.BorderEffect.Intensity = 3;

    //Appearance should be regenerated.
    circleAnnot.RegenerateAppearances();

    page.Annots.Add(circleAnnot);

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}

square annot sample

Text Markup Annotations

Text markup annotations appear as highlights, underlines, strikeouts, or squiggly underlines in the text of a document. When opened, they display a pop-up window containing the text of the associated note.

How to highlight text with color in a PDF document

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    //Get information for a range of characters.
    PdfTextInfo textInfo;
    textInfo = page.Text.GetTextInfo(0, 350);

    // Create highlight annotation around the text
    var highlightAnnot = new PdfHighlightAnnotation(page);
    highlightAnnot.QuadPoints = new PdfQuadPointsCollection();
    highlightAnnot.Color = FS_COLOR.Yellow;
    foreach (var rect in textInfo.Rects)
    {
        var x1 = rect.left;
        var y1 = rect.top;
        var x2 = rect.right;
        var y2 = rect.top;
        var x3 = rect.left;
        var y3 = rect.bottom;
        var x4 = rect.right;
        var y4 = rect.bottom;
        highlightAnnot.QuadPoints.Add(new FS_QUADPOINTSF(x1, y1, x2, y2, x3, y3, x4, y4));
    }

    //Appearance should be regenerated.
    highlightAnnot.RegenerateAppearances();

    page.Annots.Add(highlightAnnot);

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}

How to add underlines to the text of a document

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    //Get information for a range of characters.
    PdfTextInfo textInfo;
    textInfo = page.Text.GetTextInfo(328, 50);

    // Create underline annotation around the text
    var underlineAnnot = new PdfUnderlineAnnotation(page);
    underlineAnnot.QuadPoints = new PdfQuadPointsCollection();
    underlineAnnot.Color = FS_COLOR.Blue;
    foreach (var rect in textInfo.Rects)
    {
        var x1 = rect.left;
        var y1 = rect.top;
        var x2 = rect.right;
        var y2 = rect.top;
        var x3 = rect.left;
        var y3 = rect.bottom;
        var x4 = rect.right;
        var y4 = rect.bottom;
        underlineAnnot.QuadPoints.Add(new FS_QUADPOINTSF(x1, y1, x2, y2, x3, y3, x4, y4));
    }

    //Appearance should be regenerated.
    underlineAnnot.RegenerateAppearances();

    page.Annots.Add(underlineAnnot);

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}

How to add strikeouts to the text of a document

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    //Get information for a range of characters.
    PdfTextInfo textInfo;
    textInfo = page.Text.GetTextInfo(543, 212);

    // Create strikeout annotation around the text
    var strikeoutAnnot = new PdfStrikeoutAnnotation(page);
    strikeoutAnnot.QuadPoints = new PdfQuadPointsCollection();
    strikeoutAnnot.Color = FS_COLOR.Red;
    foreach (var rect in textInfo.Rects)
    {
        var x1 = rect.left;
        var y1 = rect.top;
        var x2 = rect.right;
        var y2 = rect.top;
        var x3 = rect.left;
        var y3 = rect.bottom;
        var x4 = rect.right;
        var y4 = rect.bottom;
        strikeoutAnnot.QuadPoints.Add(new FS_QUADPOINTSF(x1, y1, x2, y2, x3, y3, x4, y4));
    }

    //Appearance should be regenerated.
    strikeoutAnnot.RegenerateAppearances();

    page.Annots.Add(strikeoutAnnot);

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}

How to create jagged ("squiggly") underlines in the text of a document

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    //Get information for a range of characters.
    PdfTextInfo textInfo;
    textInfo = page.Text.GetTextInfo(543, 212);

    // Create strikeout annotation around the text
    var strikeoutAnnot = new PdfStrikeoutAnnotation(page);
    strikeoutAnnot.QuadPoints = new PdfQuadPointsCollection();
    strikeoutAnnot.Color = FS_COLOR.Red;
    foreach (var rect in textInfo.Rects)
    {
        var x1 = rect.left;
        var y1 = rect.top;
        var x2 = rect.right;
        var y2 = rect.top;
        var x3 = rect.left;
        var y3 = rect.bottom;
        var x4 = rect.right;
        var y4 = rect.bottom;
        strikeoutAnnot.QuadPoints.Add(new FS_QUADPOINTSF(x1, y1, x2, y2, x3, y3, x4, y4));
    }

    //Appearance should be regenerated.
    strikeoutAnnot.RegenerateAppearances();

    page.Annots.Add(strikeoutAnnot);

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}

textmarkup annot sample

Caret Annotations

A caret annotation is a visual symbol that indicates the presence of text edits. The following code snippets provides a quick example on how to create caret annotation in two ways.

Create the caret annotations by passing parameters to the specialized constructor

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    //With a new paragraph symbol (¶) associated with the caret.
    var caretWithNewParagrapth = new PdfCaretAnnotation(page, new FS_RECTF(50, 790, 70, 700), FS_COLOR.Red, true);
    page.Annots.Add(caretWithNewParagrapth);

    //Without a new paragraph symbol.
    var caretWithoutNewParagrapth = new PdfCaretAnnotation(page, new FS_RECTF(50, 690, 70, 600), FS_COLOR.Green, false);
    page.Annots.Add(caretWithoutNewParagrapth);

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}

Create caret annotation by setting up the annotation properties

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    var annot = new PdfCaretAnnotation(page);
    annot.Color = FS_COLOR.Blue;
    annot.Contents = "This is contents";
    annot.InnerRectangle = new float[] { 0, 0, 21, 0 };
    annot.Rectangle = new FS_RECTF(50, 590, 90, 500);
    annot.IsSymbol = true; //With a new paragraph symbol

    //Appearance should be regenerated.
    annot.RegenerateAppearances();

    page.Annots.Add(annot);

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}

caret annot sample

Ruber Stamp Annotations

A rubber stamp annotation displays text or graphics intended to look as if they were stamped on the page with a rubber stamp. When opened, it displays a pop-up window containing the text of the associated note.

Create a stamp annotation with a default style

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    page.Annots.Add(new PdfStampAnnotation(page, StampIconNames.Approved, 50, 700, FS_COLOR.DarkGreen));

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}

Create a stamp annotation with custom text

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    page.Annots.Add(new PdfStampAnnotation(page, "Custom Text", 50, 650, FS_COLOR.SteelBlue));

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}

Create a stamp annotation in your own style.

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    //Load bitmap from a file and create image object.
    var bmp = PdfBitmap.FromFile(@"e:\0\stamp.png");
    var img = PdfImageObject.Create(page.Document, bmp, 300, 650);

    var stamp = new PdfStampAnnotation(page, "", 0, 0, FS_COLOR.SteelBlue);
    //create an empty normal appearance of the annotation.
    stamp.NormalAppearance.Clear();
    //add the image to the NormalAppearance.
    stamp.NormalAppearance.Add(img);
    //Generate the NormalAppearance
    stamp.GenerateAppearance(AppearanceStreamModes.Normal);

    page.Annots.Add(stamp);

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}

stamp annot sample

Ink Annotations

An ink annotation represents a freehand “scribble” composed of one or more disjoint paths. When opened, it displays a pop-up window containing the text of the associated note.

Create an ink annotation

C#
    using (var doc = PdfDocument.Load("sample.pdf"))
    {
        var page = doc.Pages[0];
        if (page.Annots == null)
            page.CreateAnnotations();

        var annot = new PdfInkAnnotation(page);
        annot.Color = FS_COLOR.Red;
        annot.Contents = "Content of annotation";
        annot.Opacity = 1f;
        annot.LineStyle = new Patagames.Pdf.Net.Wrappers.PdfBorderStyle();
        annot.LineStyle.Style = BorderStyles.Solid;
        annot.LineStyle.Width = 3.0f;

        var points = GetInkPoints();
        annot.InkList = new PdfInkPointCollection();
        annot.InkList.Add(points);

        //Appearance should be regenerated.
        annot.RegenerateAppearances();

        page.Annots.Add(annot);

        //Save a copy of PDF document
        doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
    }

private PdfLinePointCollection<PdfInkAnnotation> GetInkPoints()
{
    var points = new PdfLinePointCollection<PdfInkAnnotation>();
    points.Add(new FS_POINTF(52.691, 777.755));
    points.Add(new FS_POINTF(50.555, 779.18));
    points.Add(new FS_POINTF(49.843, 779.18));
    points.Add(new FS_POINTF(49.487, 779.536));
    points.Add(new FS_POINTF(49.131, 779.536));
    points.Add(new FS_POINTF(48.419, 779.536));
    points.Add(new FS_POINTF(48.063, 779.892));
    points.Add(new FS_POINTF(47.351, 779.892));
    points.Add(new FS_POINTF(46.639, 779.892));
    points.Add(new FS_POINTF(45.927, 779.892));
    points.Add(new FS_POINTF(44.859, 779.892));
    points.Add(new FS_POINTF(43.791, 779.892));
    points.Add(new FS_POINTF(42.723, 779.892));
    points.Add(new FS_POINTF(41.654, 779.536));
    points.Add(new FS_POINTF(40.586, 779.536));
    points.Add(new FS_POINTF(39.518, 779.18));
    points.Add(new FS_POINTF(38.45, 778.824));
    points.Add(new FS_POINTF(37.382, 778.824));
    points.Add(new FS_POINTF(36.314, 778.468));
    points.Add(new FS_POINTF(35.246, 778.111));
    points.Add(new FS_POINTF(34.178, 777.755));
    points.Add(new FS_POINTF(33.466, 777.399));
    points.Add(new FS_POINTF(32.398, 776.687));
    points.Add(new FS_POINTF(31.33, 776.331));
    points.Add(new FS_POINTF(30.618, 775.975));
    points.Add(new FS_POINTF(29.55, 775.263));
    points.Add(new FS_POINTF(28.838, 774.906));
    points.Add(new FS_POINTF(28.482, 774.194));
    points.Add(new FS_POINTF(27.77, 773.482));
    points.Add(new FS_POINTF(27.058, 772.414));
    points.Add(new FS_POINTF(26.702, 771.701));
    points.Add(new FS_POINTF(26.346, 770.989));
    points.Add(new FS_POINTF(25.99, 770.277));
    points.Add(new FS_POINTF(25.634, 769.209));
    points.Add(new FS_POINTF(25.634, 768.496));
    points.Add(new FS_POINTF(25.634, 767.428));
    points.Add(new FS_POINTF(25.277, 766.716));
    points.Add(new FS_POINTF(25.634, 766.004));
    points.Add(new FS_POINTF(25.634, 764.935));
    points.Add(new FS_POINTF(25.99, 764.223));
    points.Add(new FS_POINTF(26.346, 763.511));
    points.Add(new FS_POINTF(26.702, 762.442));
    points.Add(new FS_POINTF(27.414, 761.374));
    points.Add(new FS_POINTF(28.126, 760.662));
    points.Add(new FS_POINTF(28.838, 759.594));
    points.Add(new FS_POINTF(29.55, 758.881));
    points.Add(new FS_POINTF(30.618, 758.169));
    points.Add(new FS_POINTF(32.042, 757.101));
    points.Add(new FS_POINTF(33.11, 756.388));
    points.Add(new FS_POINTF(34.534, 755.676));
    points.Add(new FS_POINTF(35.958, 754.964));
    points.Add(new FS_POINTF(37.738, 754.608));
    points.Add(new FS_POINTF(39.518, 754.252));
    points.Add(new FS_POINTF(41.298, 753.54));
    points.Add(new FS_POINTF(43.079, 753.183));
    points.Add(new FS_POINTF(45.215, 753.183));
    points.Add(new FS_POINTF(46.995, 752.827));
    points.Add(new FS_POINTF(48.775, 752.471));
    points.Add(new FS_POINTF(50.911, 752.471));
    points.Add(new FS_POINTF(53.047, 752.471));
    points.Add(new FS_POINTF(54.827, 752.471));
    points.Add(new FS_POINTF(56.963, 752.471));
    points.Add(new FS_POINTF(59.099, 752.827));
    points.Add(new FS_POINTF(61.236, 752.827));
    points.Add(new FS_POINTF(63.372, 753.183));
    points.Add(new FS_POINTF(65.508, 753.54));
    points.Add(new FS_POINTF(67.644, 754.252));
    points.Add(new FS_POINTF(69.78, 754.608));
    points.Add(new FS_POINTF(71.56, 755.32));
    points.Add(new FS_POINTF(73.34, 756.032));
    points.Add(new FS_POINTF(74.764, 756.388));
    points.Add(new FS_POINTF(76.188, 757.101));
    points.Add(new FS_POINTF(77.613, 757.813));
    points.Add(new FS_POINTF(78.681, 758.169));
    points.Add(new FS_POINTF(80.105, 758.881));
    points.Add(new FS_POINTF(81.173, 759.594));
    points.Add(new FS_POINTF(81.885, 760.306));
    points.Add(new FS_POINTF(82.597, 761.018));
    points.Add(new FS_POINTF(83.309, 761.73));
    points.Add(new FS_POINTF(84.021, 762.086));
    points.Add(new FS_POINTF(84.733, 762.799));
    points.Add(new FS_POINTF(85.089, 763.511));
    points.Add(new FS_POINTF(85.801, 764.579));
    points.Add(new FS_POINTF(86.157, 765.291));
    points.Add(new FS_POINTF(86.157, 766.36));
    points.Add(new FS_POINTF(86.513, 767.072));
    points.Add(new FS_POINTF(86.869, 767.784));
    points.Add(new FS_POINTF(86.869, 768.853));
    points.Add(new FS_POINTF(86.869, 769.921));
    points.Add(new FS_POINTF(86.513, 770.633));
    points.Add(new FS_POINTF(86.513, 771.701));
    points.Add(new FS_POINTF(85.801, 772.414));
    points.Add(new FS_POINTF(85.445, 773.126));
    points.Add(new FS_POINTF(84.733, 773.482));
    points.Add(new FS_POINTF(84.021, 774.194));
    points.Add(new FS_POINTF(82.953, 774.55));
    points.Add(new FS_POINTF(81.529, 775.263));
    points.Add(new FS_POINTF(80.461, 775.619));
    points.Add(new FS_POINTF(79.037, 775.619));
    points.Add(new FS_POINTF(77.613, 775.975));
    points.Add(new FS_POINTF(75.832, 775.975));
    points.Add(new FS_POINTF(74.408, 776.331));
    points.Add(new FS_POINTF(72.984, 776.331));
    points.Add(new FS_POINTF(71.204, 776.331));
    points.Add(new FS_POINTF(69.424, 776.331));
    points.Add(new FS_POINTF(67.644, 776.331));
    points.Add(new FS_POINTF(65.508, 775.975));
    points.Add(new FS_POINTF(63.728, 775.619));
    points.Add(new FS_POINTF(62.304, 775.619));
    points.Add(new FS_POINTF(60.524, 775.263));
    points.Add(new FS_POINTF(58.743, 774.906));
    points.Add(new FS_POINTF(57.319, 774.55));
    points.Add(new FS_POINTF(55.895, 774.194));
    points.Add(new FS_POINTF(54.827, 773.838));
    points.Add(new FS_POINTF(53.759, 773.838));
    points.Add(new FS_POINTF(52.335, 773.482));
    points.Add(new FS_POINTF(51.623, 773.126));
    points.Add(new FS_POINTF(50.911, 772.77));
    points.Add(new FS_POINTF(50.199, 772.414));
    points.Add(new FS_POINTF(49.487, 772.414));
    points.Add(new FS_POINTF(48.775, 771.701));
    points.Add(new FS_POINTF(47.707, 771.345));

    return points;
}

ink annot sample

Popup Annotations

A pop-up annotation displays text in a pop-up window for entry and editing. It typically does not appear alone but is associated with a markup annotation, its parent annotation, and is used for editing the parent’s text. It has no appearance stream or associated actions of its own and is identified by the Popup property in the parent’s annotation.

Create a popup annotation

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    var textAnnot = new PdfTextAnnotation(page, IconNames.Comment, "content of popup annotation", "popup subject", 50, 700);
    bool isOpen = true; //A flag specifying whether the pop-up annotation should initially be displayed open
    var popupAnnot = new PdfPopupAnnotation(page, textAnnot, isOpen);
    page.Annots.Add(textAnnot);
    page.Annots.Add(popupAnnot);

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}
File Attachment Annotations

A file attachment annotation contains a reference to a file, which typically is embedded in the PDF file; For example, a table of data might use a file attachment annotation to link to a spreadsheet file based on that data; activating the annotation extracts the embedded file and gives the user an opportunity to view it or store it in the file system.

The Contents property of annotation may specify descriptive text relating to the attached file. Viewer applications should use this property rather than the optional Description property in the FileSpecification property.

Create a file attachment annotation

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    byte[] data = System.IO.File.ReadAllBytes("sample.txt");
    var annot = new PdfFileAttachmentAnnotation(page, FileIconNames.PushPin, "sample.txt", data, 50, 700);
    page.Annots.Add(annot);

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}

file annot sample

How to get file content from file annotation.

C#
using (var doc = PdfDocument.Load("sample_withAnnot.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        return;

    foreach(var annot in page.Annots)
    {
        var fileAnnot = annot as PdfFileAttachmentAnnotation;
        if (fileAnnot == null)
            continue;

        PdfFileSpecification fileSpec = fileAnnot.FileSpecification;
        if (fileSpec == null)
            continue;

        PdfFile embeddedFile = fileSpec.EmbeddedFile;
        if (embeddedFile == null)
            continue;

        PdfTypeStream fileStream = embeddedFile.Stream;
        if (fileStream == null)
            continue;

        byte[] fileContent = fileStream.DecodedData;
    }
}
Sound Annotations

A sound annotation is analogous to a text annotation except that instead of a text note, it contains sound recorded from the computer’s microphone or imported from a file. When the annotation is activated, the sound is played. The annotation behaves like a text annotation in most ways, with a different icon to indicate that it represents a sound.

Create a file attachment annotation

C#
using (var doc = PdfDocument.Load("sample.pdf"))
{
    var page = doc.Pages[0];
    if (page.Annots == null)
        page.CreateAnnotations();

    byte[] data = System.IO.File.ReadAllBytes(@"e:\0\sample.wav");
    PdfSound sound = PdfSound.FromWave(data);
    var annot = new PdfSoundAnnotation(page, SoundIconNames.Speaker, 50, 700, sound);
    page.Annots.Add(annot);

    //Save a copy of PDF document
    doc.Save("sample_withAnnot.pdf", SaveFlags.NoIncremental);
}

sound annot sample

See Also