---
title: "Highlight text in a PDF in C#"
url: https://recursiveai.org/onepdf/cookbook/highlight-pdf-text/
description: "Add a yellow highlight and a review comment without changing the underlying text. Free, open-source OnePDF example for .NET 10."
version: "1.22.0"
---

# Highlight text in a PDF in C#

**OnePDF** is a free, open-source PDF library for .NET from Recursive AI. MIT or Apache-2.0, no native dependencies.

[NuGet](https://www.nuget.org/packages/RecursiveAI.OnePdf) · [GitHub](https://github.com/recursive-ai-oss/onepdf-csharp) · [Docs](https://recursiveai.org/onepdf/docs/) · [Download example (.zip)](https://recursiveai.org/onepdf/cookbook/highlight-pdf-text/highlight-pdf-text.zip)

Add a yellow highlight and a review comment without changing the underlying text.

```shell
dotnet add package RecursiveAI.OnePdf
```

Requires [.NET 10](https://dotnet.microsoft.com/download/dotnet/10.0) (net10.0); .NET 9 and earlier aren’t supported.

`input.pdf` is the three-page sample in the example zip.

```csharp
using OnePdf;

using var doc = PdfDocument.Open("input.pdf",
    new PdfOpenOptions { AllowEditing = true });
doc.Pages[0].AddMarkupAnnotation(new()
{
    Kind = PdfMarkupKind.Highlight,
    Quads = [PdfMarkupQuad.FromRectangle(
        new PdfRectangle(72, 697, 110, 712))],
    Color = [1, 1, 0],
    Contents = "Check this figure"
});
doc.Save("highlighted.pdf");
Console.WriteLine("Saved highlighted.pdf");
```

```text
Saved highlighted.pdf
```

Unzip [the example](https://recursiveai.org/onepdf/cookbook/highlight-pdf-text/highlight-pdf-text.zip), then `dotnet run`.

`input.pdf` is included in the zip: an original, public-domain sample with three identical, unrotated pages. Each page contains this line in 12-point Helvetica at (72, 700):

```text
Review this figure
```

## The full program

The four `PdfRectangle(72, 697, 110, 712)` numbers are left, bottom, right and top, in points measured from the bottom-left on this sample page. The full program finds these coordinates for you by extracting the word “Review” on the first page, then highlights its bounds and reopens the result to read the annotation.

```csharp
using OnePdf;

using var doc = PdfDocument.Open("input.pdf",
    new PdfOpenOptions { AllowEditing = true });
var page = doc.Pages[0];
// This sample has upright text and no page rotation.
var words = page.ExtractText().Blocks
    .SelectMany(block => block.Lines)
    .SelectMany(line => line.Words)
    .Where(word => word.Text == "Review").ToArray();
if (words.Length == 0)
    throw new InvalidOperationException("Review was not found.");
page.AddMarkupAnnotation(new()
{
    Kind = PdfMarkupKind.Highlight,
    Quads = words.Select(word =>
        PdfMarkupQuad.FromRectangle(word.Bounds)).ToArray(),
    Color = [1, 1, 0],
    Contents = "Check this figure",
    Title = "Reviewer",
    Name = "review-1"
});
doc.Save("highlighted.pdf");
using var saved = PdfDocument.Open("highlighted.pdf");
var annotation = saved.Pages[0].Annotations.Single();
Console.WriteLine($"Matched words: {words.Length}");
Console.WriteLine($"{annotation.Subtype}: {annotation.Contents}");
```

`dotnet run` prints:

```text
Matched words: 1
Highlight: Check this figure
```

Invalid markup geometry throws `ArgumentException` before the annotation is added.

## Variations

Underline the same known rectangle and append an incremental update:

```csharp
using OnePdf;

using var doc = PdfDocument.Open("input.pdf",
    new PdfOpenOptions { AllowEditing = true });
doc.Pages[0].AddMarkupAnnotation(new()
{
    Kind = PdfMarkupKind.Underline,
    Quads = [PdfMarkupQuad.FromRectangle(
        new PdfRectangle(72, 697, 110, 712))],
    Contents = "Check this word"
});
using (var output = File.Create("underlined.pdf"))
    doc.SaveIncremental(output);
Console.WriteLine("Saved underlined.pdf");
```

```text
Saved underlined.pdf
```

## Related recipes

- [Redact a PDF](https://recursiveai.org/onepdf/cookbook/redact/)
- [Extract PDF text](https://recursiveai.org/onepdf/cookbook/extract-text/)

## The short answer

Open the PDF with editing enabled, identify the text’s position, and pass explicit quadrilaterals to `AddMarkupAnnotation` with `Kind = PdfMarkupKind.Highlight`. Save the result to another path. OnePDF creates the annotation’s normal appearance as well as its geometry, so the file carries the drawing of the highlight, not just a request for a viewer to invent one.

The snippet at the top marks a known rectangle. The full program extracts words and marks the word “Review” using its bounds. Both add review markup; neither deletes or replaces the page’s text.

## How can I highlight text in a PDF for free?

OnePDF is free and open source under MIT or Apache-2.0. Install `RecursiveAI.OnePdf` in a .NET 10 project and open the file with `AllowEditing = true`. No separate annotation package is needed. Set `Contents` to the review comment and `Title` to the reviewer’s name if you want that information in the annotation.

The [markup documentation](https://recursiveai.org/onepdf/docs/markup-annotations/) describes the generated appearance: a highlight uses the Multiply blend mode. Color components are numbers between zero and one. Three components specify RGB, so `[1, 1, 0]` is yellow. `Opacity` is optional. The default annotation flags include Print, allowing a viewer to include the annotation when printing.

A comment is annotation data, not new page text. Whether a viewer opens a comment panel automatically is separate from storing the comment. You can supply an explicit `Popup` when you need a linked pop-up annotation and its rectangle.

## Is there a way to highlight text in a PDF?

Yes, when you know the geometry. For a searchable PDF, extract the page’s blocks, lines and words and select the words you want. The full program uses an exact, case-sensitive word match. It does not implement phrase matching, substring matching or optical character recognition. A scan without a text layer will not produce the target word through this extraction path.

For upright text on an unrotated page, `PdfMarkupQuad.FromRectangle(word.Bounds)` covers the word. For a phrase spanning lines, keep the separate word or line areas rather than making one large rectangle that also covers the intervening whitespace.

Rotated text needs more care. [Text extraction](https://recursiveai.org/onepdf/docs/text-layout/) reports geometry in upright page space with the page’s rotation applied. Markup quadrilaterals use default user space: the page’s stored coordinates before display rotation or cropping, with y increasing upward. On this sample, the origin is at the bottom-left and one point is 1/72 inch; a PDF’s `UserUnit` can change that scale. See [drawing coordinates](https://recursiveai.org/onepdf/docs/content-creation/) for the coordinate rules. Convert between those spaces for rotated pages before constructing the quads. For angled text, an axis-aligned word box is not its oriented outline: construct the four corners explicitly. The corners are ordered upper left, upper right, lower left, lower right, with “upper” defined relative to the text’s ascenders, not necessarily the page’s top.

## How do I highlight text in a PDF and save it?

Use `Save` for an ordinary full rewrite. Reopen the result and read `Pages[0].Annotations` to inspect the subtype and comment, as the full program does. Extraction ignores annotations, so it still returns the original text rather than the comment.

On signed files, use `SaveIncremental` to retain the original bytes. Retaining signed bytes does not mean every modification is permitted. Certification levels describe changes the signer permits: P=1 allows no changes; P=2 allows form filling and signing; P=3 also allows annotation changes. The [signed-file rules](https://recursiveai.org/onepdf/docs/markup-annotations/#signed-files) allow new markup for certification level P=3, but report annotation changes as disallowed for P=1 or P=2. Approval signatures without certification have the library’s documented conservative allowance only when the update appends the supported markup and linked pop-ups without other changes. A full save rewrites the file and drops the signatures’ coverage.
