How PDF coordinate systems work with UniPDF
There are two coordinate systems in play, and they disagree about which way y goes.
PDF user space is a flat, device-independent plane measured in points, 72 to the inch. Its
origin is the bottom left corner of the page, x grows to the right and y grows upward.
Everything stored in the file uses it: the media box, annotation rectangles, the operands
in a content stream. A US Letter page is 612 by 792 points; A4 is about 595 by 842.
The creator package flips it. Position 0, 0 is the top left corner of the page and y
grows downward, for every component that has a SetPos. This is the one thing to get
straight before placing anything by hand, because both systems use the same units and the
same numbers, so an image placed with the wrong one lands mirrored about the middle of the
page rather than erroring.
img.SetPos(72, 72) // one inch in from the left, one inch down from the topConverting between the two is a subtraction against the page height:
yPDF := c.Height() - yCreatorRectangles stored in the file are two corners rather than a position and a size.
model.PdfRectangle names them Llx, Lly, Urx and Ury, and that is the order they
appear in when a rectangle is written as an array. An annotation rect of
[]float64{123.97, 619.02, 343.99, 633.6} is a box whose lower left corner is at
(123.97, 619.02) and whose upper right corner is at (343.99, 633.6), so it is 220 points
wide, about 15 points tall, and in the upper third of a Letter page.
creator.Rectangle is the odd one out: it is defined by its upper left corner plus a width
and height, matching the creator’s own top-left origin rather than the file format’s.
The 72 points per inch figure is fixed for user space. Page contents can be scaled by a
transformation matrix, and a page can carry a /UserUnit entry that rescales the whole
thing, but neither changes what a point means to the calls above.
For the drawing primitives see apidocs.unidoc.io, or email UniDoc Support.