Drawing on Pages
Draw text, lines, and rectangles directly onto existing PDF pages using the PDFium-backed drawing API. Unlike stamps (which composite a separate PDF), drawing methods modify the page content stream in place — ideal for adding approval marks, highlight boxes, borders, and annotations that need precise pixel-level placement.
Coordinate System
PDF uses a coordinate system where:
- The origin (0, 0) is at the bottom-left corner of the page.
- The X axis increases to the right.
- The Y axis increases upward.
- All measurements are in PDF points (1 point = 1/72 inch).
| Paper Size | Width (points) | Height (points) |
|---|---|---|
| A4 Portrait | 595 | 842 |
| A4 Landscape | 842 | 595 |
| US Letter Portrait | 612 | 792 |
| US Letter Landscape | 792 | 612 |
| US Legal Portrait | 612 | 1008 |
Bottom-left origin. This is the standard PDF coordinate convention. A point at (50, 800) on an A4 page is 50 points from the left edge and 800 points from the bottom — which places it near the top of the page. If you are used to screen coordinates (origin at top-left), remember that y = pageHeight - desiredDistanceFromTop.
Drawing Text
Place text at an exact position on a specific page:
PdfEditor.Open("form.pdf")
.DrawText(
pageIndex: 0,
text: "Approved",
x: 400,
y: 50,
fontSize: 18,
fontName: "Helvetica",
r: 0, g: 128, b: 0)
.Save("form-approved.pdf");
DrawText Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
pageIndex | int | — | Zero-based page index. |
text | string | — | The text to draw. |
x | float | — | X coordinate in PDF points (from left edge). |
y | float | — | Y coordinate in PDF points (from bottom edge). |
fontSize | float | 12 | Font size in points. |
fontName | string | "Helvetica" | A standard PDF font name (see table below). |
r | byte | 0 | Red component (0–255). |
g | byte | 0 | Green component (0–255). |
b | byte | 0 | Blue component (0–255). |
Standard PDF Fonts
These fonts are built into every PDF viewer and do not require embedding:
| Font Name | Style |
|---|---|
Helvetica | Sans-serif (default) |
Helvetica-Bold | Sans-serif bold |
Helvetica-Oblique | Sans-serif italic |
Helvetica-BoldOblique | Sans-serif bold italic |
Times-Roman | Serif |
Times-Bold | Serif bold |
Times-Italic | Serif italic |
Times-BoldItalic | Serif bold italic |
Courier | Monospace |
Courier-Bold | Monospace bold |
Courier-Oblique | Monospace italic |
Courier-BoldOblique | Monospace bold italic |
Symbol | Symbol characters |
ZapfDingbats | Dingbats / ornaments |
Drawing Lines
Draw a straight line between two points on a page:
PdfEditor.Open("document.pdf")
.DrawLine(
pageIndex: 0,
x1: 50, y1: 750,
x2: 545, y2: 750,
strokeWidth: 2,
r: 0, g: 0, b: 0)
.Save("document-with-line.pdf");
DrawLine Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
pageIndex | int | — | Zero-based page index. |
x1 | float | — | Starting X coordinate. |
y1 | float | — | Starting Y coordinate. |
x2 | float | — | Ending X coordinate. |
y2 | float | — | Ending Y coordinate. |
strokeWidth | float | 1 | Line thickness in points. |
r | byte | 0 | Red component (0–255). |
g | byte | 0 | Green component (0–255). |
b | byte | 0 | Blue component (0–255). |
Drawing Rectangles
Draw a rectangle with an optional fill colour:
// Stroke only (no fill)
PdfEditor.Open("form.pdf")
.DrawRectangle(
pageIndex: 0,
x: 50, y: 700,
width: 200, height: 30,
strokeWidth: 1,
strokeR: 255, strokeG: 0, strokeB: 0)
.Save("form-highlighted.pdf");
// Filled rectangle with semi-transparent yellow
PdfEditor.Open("report.pdf")
.DrawRectangle(
pageIndex: 0,
x: 50, y: 700,
width: 495, height: 30,
strokeWidth: 0,
strokeR: 0, strokeG: 0, strokeB: 0,
fillR: 255, fillG: 255, fillB: 0,
fillAlpha: 80)
.Save("report-highlighted.pdf");
DrawRectangle Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
pageIndex | int | — | Zero-based page index. |
x | float | — | X of the bottom-left corner. |
y | float | — | Y of the bottom-left corner. |
width | float | — | Rectangle width in points. |
height | float | — | Rectangle height in points. |
strokeWidth | float | 1 | Border thickness. Use 0 for no border. |
strokeR, strokeG, strokeB | byte | 0 | Stroke colour (RGB 0–255). |
fillR | int | -1 | Fill red component. Pass -1 for no fill. |
fillG, fillB | int | 0 | Fill green and blue components (ignored when fillR is -1). |
fillAlpha | byte | 255 | Fill alpha (0 = transparent, 255 = opaque). |
No-fill mode. When fillR is -1, the rectangle is stroke-only with no fill. Set fillR to 0 or higher to enable filling.
Practical Examples
Approval Stamp Box
Draw a bordered box with approval text inside it, placed in the bottom-right corner of the first page:
float boxX = 400, boxY = 30;
float boxW = 160, boxH = 50;
PdfEditor.Open("contract.pdf")
// Green border rectangle
.DrawRectangle(0, boxX, boxY, boxW, boxH,
strokeWidth: 2,
strokeR: 0, strokeG: 128, strokeB: 0,
fillR: 240, fillG: 255, fillB: 240, fillAlpha: 200)
// "APPROVED" text
.DrawText(0, "APPROVED", boxX + 15, boxY + 28,
fontSize: 18, fontName: "Helvetica-Bold",
r: 0, g: 128, b: 0)
// Date line
.DrawText(0, $"{DateTime.Now:yyyy-MM-dd}", boxX + 15, boxY + 10,
fontSize: 10, fontName: "Helvetica",
r: 80, g: 80, b: 80)
.Save("contract-approved.pdf");
Page Border
Draw a border around the entire page content area (50-point margin on an A4 page):
float margin = 50;
float pageW = 595, pageH = 842;
PdfEditor.Open("report.pdf")
.DrawRectangle(0,
x: margin, y: margin,
width: pageW - 2 * margin,
height: pageH - 2 * margin,
strokeWidth: 1,
strokeR: 180, strokeG: 180, strokeB: 180)
.Save("report-bordered.pdf");
Highlight Box Over a Region
Draw a semi-transparent yellow box to highlight a specific area:
PdfEditor.Open("document.pdf")
.DrawRectangle(0,
x: 72, y: 500,
width: 300, height: 20,
strokeWidth: 0,
strokeR: 0, strokeG: 0, strokeB: 0,
fillR: 255, fillG: 255, fillB: 0,
fillAlpha: 64)
.Save("document-highlighted.pdf");
Separator Lines Between Sections
PdfEditor.Open("report.pdf")
// Thin grey line across the page at y=600
.DrawLine(0, x1: 50, y1: 600, x2: 545, y2: 600,
strokeWidth: 0.5f, r: 180, g: 180, b: 180)
// Thicker coloured line at y=400
.DrawLine(0, x1: 50, y1: 400, x2: 545, y2: 400,
strokeWidth: 2, r: 0, g: 102, b: 204)
.Save("report-with-dividers.pdf");
Drawing on Multiple Pages
Draw a footer line and page label on every page of a document:
using var inspector = PdfiumDocument.Load(File.ReadAllBytes("manual.pdf"));
int pageCount = inspector.PageCount;
inspector.Dispose();
var editor = PdfEditor.Open("manual.pdf");
for (int i = 0; i < pageCount; i++)
{
// Footer line
editor.DrawLine(i,
x1: 50, y1: 40,
x2: 545, y2: 40,
strokeWidth: 0.5f,
r: 150, g: 150, b: 150);
// Page number text
editor.DrawText(i, $"Page {i + 1} of {pageCount}",
x: 480, y: 25,
fontSize: 9,
fontName: "Helvetica",
r: 120, g: 120, b: 120);
}
editor.Save("manual-with-footers.pdf");
Redaction-Style Black Box
Cover a region with an opaque black rectangle (for visual redaction when formal redaction is not needed):
PdfEditor.Open("report.pdf")
.DrawRectangle(0,
x: 200, y: 710,
width: 180, height: 14,
strokeWidth: 0,
strokeR: 0, strokeG: 0, strokeB: 0,
fillR: 0, fillG: 0, fillB: 0, fillAlpha: 255)
.Save("report-redacted.pdf");
True redaction. Drawing a black box over text is not true redaction — the original text remains in the PDF's content stream and can be extracted. For proper content removal, use PdfEditor.RedactText() or PdfEditor.RedactArea() instead.
Drawing vs Stamping
| Feature | Drawing API | Stamp API |
|---|---|---|
| Precision placement | Exact X/Y coordinates | Alignment-based (Start/Center/End) |
| Per-page control | Targets a specific page | Applies to all pages |
| Typography | Standard PDF fonts only | Full layout engine (any font) |
| Shapes | Lines, rectangles | Text and images only |
| Mechanism | Modifies page content stream | Generates overlay PDF + qpdf merge |
| Best for | Approval marks, borders, highlights | Watermarks, logos, branding |
Next Steps
- Stamping & Watermarks — alignment-based text and image stamps
- Page Manipulation — rotation, page boxes, coordinate system details
- Text Extraction — read text and positions from existing pages