PDF coordinates and units in PdfNetStack
Two coordinate systems, one unit: what each API uses, and how to convert between them.
Short answer
Section titled “Short answer”Everything is in points, 1/72 inch. When you create content (drawing, annotations, form fields),
the origin is the top left corner of the page and y points down. When you read content back (text,
images, annotation and widget rectangles), positions are in PDF default user space: origin bottom
left, y up, before the page’s /Rotate.
// One point is 1/72 inch. Convert once, draw in points.static double Mm(double millimetres) => millimetres * 72 / 25.4;static double Inches(double inches) => inches * 72;
PdfDocument doc = PdfDocument.Create();PdfPage page = doc.Pages.Add(PdfRectangle.A4); // 595 x 842 points, about 210 x 297 mmusing (PdfGraphics g = page.CreateGraphics()){ // A box 20 mm from the left and 30 mm from the top: y grows downward on the canvas. g.DrawRectangle(PdfPen.Black, null, Mm(20), Mm(30), Mm(80), Mm(15)); g.DrawString("Hello", PdfStandardFont.Helvetica, 12, PdfColor.Black, Mm(20) + 6, Mm(30) + 26); g.DrawLine(PdfPen.Black, Inches(1), Inches(2), Inches(3), Inches(2));}doc.Save("coordinates.pdf");| Unit | Points |
|---|---|
| 1 inch | 72 |
| 1 cm | 28.35 (72 / 2.54) |
| 1 mm | 2.835 (72 / 25.4) |
| CSS pixel | 0.75 (96 per inch) |
PdfRectangle.A4 is 595 by 842 points (210 by 297 mm, rounded), PdfRectangle.Letter 612 by 792.
PdfRectangle.FromSize(width, height) makes any other size, such as FromSize(842, 595) for A4
landscape. Images drawn at their natural size use the resolution the file records, else 96 pixels
per inch.
Creating content: top left, y down
Section titled “Creating content: top left, y down”| API | Origin |
|---|---|
PdfPage.CreateGraphics() and every PdfGraphics method | Top left corner of the media box, y down |
Every page.Annotations.Add... method: links, notes, markup, free text, stamps, shapes, lines, ink, attachments | Same as the canvas |
doc.Form.AddTextField and the other field methods | Same as the canvas |
PdfForm.CreateGraphics() | Top left corner of the form |
PdfTextLayout lines (Top, Baseline, Left) | Top left corner of the laid out paragraph |
Two details matter when placing text:
DrawString(text, font, size, brush, x, y)puts the start of the baseline at (x, y). Addfont.Ascent * sizeto y to place the top of the line instead.DrawText(paragraph, x, y, width)puts the top left corner of the paragraph at (x, y).
Canvas transforms (TranslateTransform, RotateTransform and the others) change where later
drawing lands. Positive rotation angles turn clockwise on the canvas. PdfGraphics.AddLink follows
the current transform; the annotation methods on page.Annotations do not.
Reading content: bottom left, y up
Section titled “Reading content: bottom left, y up”| API | Coordinates |
|---|---|
PdfPage.GetWords(), GetLetters(): Bounds, BaselineStart, BaselineEnd | Default user space, before /Rotate |
PdfPage.GetImages(): Bounds, Transform | Default user space, before /Rotate |
PdfAnnotation.Rectangle, PdfWidget.Rectangle | PDF user space |
PdfPage.MediaBox, CropBox | PDF user space, as PdfRectangle(Left, Bottom, Right, Top) |
// Extraction reports default user space: origin bottom left, y up.PdfWord word = PdfDocument.Open("coordinates.pdf").Pages[0].GetWords()[0];Console.WriteLine($"{word.Text}: left {word.Bounds.Left:F1}, bottom {word.Bounds.Bottom:F1}, top {word.Bounds.Top:F1}");
// Back to canvas coordinates: y from the top is the page height minus y from the bottom.double canvasTop = page.MediaBox.Top - word.Bounds.Top;Console.WriteLine($"On the canvas the word's top is {canvasTop:F1} points from the top");To convert a point from user space to the canvas: x = pdfX - page.MediaBox.Left and
y = page.MediaBox.Top - pdfY. For a rectangle, its canvas top is MediaBox.Top - rect.Top and its
height stays rect.Height. That is how you place a highlight over a word that text extraction
found.
Rotated pages
Section titled “Rotated pages”PdfPage.Rotation is the clockwise rotation a viewer applies when it displays the page: 0, 90, 180
or 270. Rotate(degrees) adds to it.
- The canvas does not apply
/Rotate: coordinates are those of the unrotated page. On a page rotated by 90 degrees, what you draw at the canvas top shows on the right side in a viewer. - Extraction positions are also before
/Rotate. PdfForm.FromPageshows a page upright, as its rotation shows it, so placing a rotated page on another page needs no extra turn.
Media box and crop box
Section titled “Media box and crop box”The media box is the page boundary; it defaults to US Letter when a file does not define one. The
crop box is the visible region and defaults to the media box. The canvas origin is the top left of
the media box, and PdfForm.FromPage shows the crop box.