SnapTools
PDF

Inside a PDF: pages, objects and what your document really contains

6 min read · updated 2026-07-21

Open a PDF in a text editor and you will not find pages. You will find something stranger: hundreds of numbered objects — dictionaries, streams, arrays — cross-referencing each other by number. A PDF is not a stack of page images. It is a small database of objects, and the "pages" you see are assembled from it every time the file is opened.

Once you see the file this way, a lot of otherwise puzzling PDF behaviour makes sense: why merging two files is fast and lossless, why editing a sentence is genuinely difficult, and why a file can carry information you never intended to share.

The object graph

Every PDF is built from indirect objects, each with a number, like 12 0 obj ... endobj. Objects refer to each other by number: 12 0 R means "see object 12". At the end of the file, a cross-reference table records the byte offset of every object, so a reader can jump straight to object 12 without scanning the whole file. That is why PDFs open quickly even when they are hundreds of megabytes: the reader loads the cross-reference table, finds the root object (the document catalogue), and follows references only as needed.

From the catalogue, references fan out into a tree:

  • The catalogue points to the page tree.
  • The page tree points to individual page objects.
  • Each page object points to a content stream (the drawing instructions), a resources dictionary (fonts, images, colour spaces the page uses), and its media box (the page dimensions).

The content stream is where the visible page lives. It is a sequence of low-level drawing operators: move to this coordinate, set this font at this size, show this string of glyphs, paint this image at this position. Text in a PDF is not a paragraph — it is a series of "place these characters at these coordinates" instructions. There is no concept of a sentence, a column, or a line wrap.

Images and fonts are shared resources. If the same logo appears on fifty pages, a well-made PDF stores it once as an image XObject and references it fifty times. Fonts are usually embedded as subsets: only the glyphs actually used are included, which is why copying text out of some PDFs produces garbage — the embedded subset may lack the mapping back to real characters.

Why merging is easy and editing is hard

Merging two PDFs is object surgery, not printing. A merge tool copies the page objects from document B into document A, renumbers them so the object numbers do not collide, copies across every object they reference (content streams, fonts, images), and appends the new page references to A's page tree. Nothing is rasterised, recompressed or re-laid-out. The pages arrive byte-for-byte intact, which is why merged output is the same quality as the input and why merging a 200-page file takes a moment, not minutes.

The same logic applies to splitting, reordering and rotating. Reordering pages just rewrites the array of page references in the page tree. Rotating a page sets a single /Rotate entry on the page object. These are cheap operations on the graph, and they are exactly what page-organiser tools do.

Editing the content of a page is a different job entirely. To change one word, an editor must parse the content stream, work out which glyph-positioning instructions form that word (they may be split across several operators, kerned individually), substitute new glyphs — hoping the embedded font subset contains the letters you now need — and then reflow… except there is no reflow, because the PDF never knew about lines and paragraphs. The surrounding text will not move to make room. This is why "edit PDF" features often work by covering the old text with a white box and drawing new text on top, and why the honest advice is to edit the source document and export again.

Metadata: the Info dictionary and XMP

PDFs carry metadata in two places, and they can disagree.

The older mechanism is the Info dictionary: a simple set of keys — Title, Author, Subject, Keywords, Creator (the application that made the original document), Producer (the software that generated the PDF), CreationDate and ModDate. The newer mechanism is an XMP packet: an XML blob embedded as a stream, holding the same fields plus arbitrary extras, in a format shared with images and other media.

This is worth caring about because metadata is written silently. A CV exported from a word processor will typically record the registered author name and the exact creation timestamp. Producer strings reveal the software and version used. Files that have passed through several tools can accumulate history in XMP. None of this appears on the page, but all of it travels with the file, and anyone can read it in seconds. If a document is going somewhere sensitive, inspect and strip both the Info dictionary and the XMP packet before sending — and remember that because they are stored separately, cleaning one does not clean the other.

One more wrinkle: PDFs support incremental updates. Instead of rewriting the file, a tool can append changed objects and a new cross-reference table to the end, leaving the original bytes untouched. That is efficient — and it means the previous version of an "edited" document may still be sitting in the file, recoverable by anyone who reads the earlier cross-reference table. A full "save as" rewrite discards the history; an incremental save does not.

Forms and flattening

Fillable forms are another layer of objects. The document catalogue can reference an AcroForm dictionary listing the form's fields — text boxes, checkboxes, radio groups, dropdowns, signature fields. Each field is linked to a widget annotation that sits on a page and defines where the field is drawn. Crucially, the field's value is data, stored in the field object, separate from the page's content stream.

That separation is what makes forms editable: a viewer can change the value without touching the page. It is also why a filled form can behave oddly in software that ignores AcroForm — the values may not display, because they were never part of the page's drawing instructions.

Flattening resolves this. It takes each field's current appearance, stamps it permanently into the page content stream, and deletes the interactive field objects. After flattening, the answers are just ink on the page: visible everywhere, editable nowhere. Flatten when a form is final and must not be altered; do not flatten while anyone still needs to change an answer, because there is no unflatten.

Digital signatures are a special field type with a further trick: the signature stores a cryptographic digest of the file's bytes, so any later modification — even an innocent one — is detectable. This is also why signing tools rely on incremental updates: they must append the signature without disturbing the signed bytes.

What this means in practice

  • Assembling documents — merging, splitting, reordering, rotating — is safe, fast and lossless, because it only rearranges the object graph.
  • Editing page content is inherently lossy and awkward; prefer regenerating the PDF from its source.
  • Check metadata before sharing anything sensitive: both the Info dictionary and the XMP packet, and be aware incremental updates can preserve old versions.
  • Flatten forms only when they are final; sign documents last, because signing freezes the bytes.

A PDF, in short, is less like a photograph of your document and more like a box of labelled parts with assembly instructions. Tools that respect that structure can do a great deal without ever degrading the pages — and knowing where the parts live tells you exactly what your file is really carrying.