![]() | Get access, create and manipulate annotations |
This topic contains the following sections:
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 |
---|---|---|---|
3D annotation | No | No | |
Caret annotation | Yes | Yes | |
Circle annotation | Yes | Yes | |
File attachment annotation | Yes | Yes | |
Free text annotation | Yes | Yes | |
Highlight annotation | Yes | Yes | |
Ink annotation | Yes | Yes | |
Line annotation | Yes | Yes | |
Link annotation | No | Yes | |
Movie annotation | No | No | |
Polygon annotation | Yes | Yes | |
Polyline annotation | Yes | Yes | |
Pop-up annotation | No | Yes | |
Printer’s mark annotation | No | No | |
Screen annotation | No | No | |
Sound annotation | Yes | Yes | |
Square annotation | Yes | Yes | |
Squiggly-underline annotation | Yes | Yes | |
Rubber stamp annotation | Yes | Yes | |
Strikeout annotation | Yes | Yes | |
Text annotation | Yes | Yes | |
Trap network annotation | No | No | |
Underline annotation | Yes | Yes | |
Watermark annotation | No | Yes | |
Widget annotation | No | No |
![]() |
---|
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
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.
The following code snippets provides a quick example on how to retrieve annotations using the PdfPageAnnots property.
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;
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.
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 }
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.
if (page.Annots == null) page.CreateAnnotations(); //create an empty annotation collection PdfAnnotationCollection annots = page.Annots;
Now annots is an empty PdfAnnotationCollection
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.
![]() |
---|
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.
//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);
![]() |
---|
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. |
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:
public void CreateTextAnnotationWithOneLineOfCode(PdfPage page) { page.Annots.Add(new PdfTextAnnotation(page, IconNames.Comment, FS_COLOR.Yellow, "Comment", "Subject", 80.0f, 750.0f)); }
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.
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); }
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.
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); }
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); }
A link annotation represents either a hypertext link to a destination elsewhere in the document or an action to be performed.
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); }
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); }
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); }
A line annotation displays a single straight line on the page. The following figures show some aspects of line annotation.
Name | Appearance | Description |
---|---|---|
Square | ![]() | A square filled with the annotation’s interior color, if any |
Circle | ![]() | A circle filled with the annotation’s interior color, if any |
Diamond | ![]() | A diamond shape filled with the annotation’s interior color, if any |
OpenArrow | ![]() | Two short lines meeting in an acute angle to form an open arrowhead |
ClosedArrow | ![]() | 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 | ![]() | No line ending |
Butt | ![]() | A short line at the endpoint perpendicular to the line itself |
ROpenArrow | ![]() | Two short lines in the reverse direction from OpenArrow |
RClosedArrow | ![]() | A triangular closed arrowhead in the reverse direction from ClosedArrow |
Slash | ![]() | A short line at the endpoint approximately 30 degrees clockwise from perpendicular to the line itself |
The following code snippet provides a quick example on how to create line annotation.
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.
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.
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.
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); }
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); }
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.
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); }
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.
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); }
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); }
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); }
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); }
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.
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); }
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); }
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); }
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); }
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.
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); }
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); }
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.
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); }
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); }
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); }
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.
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; }
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.
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); }
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.
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); }
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; } }
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.
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); }