Each is its own module with its own release line, so a program takes the reader without the rasteriser, or the rasteriser without the writer.
Reads and writes the format itself. Lexer and object model, cross-reference tables and streams with hybrid files and /Prev chains, object streams, repair by scanning when the table is wrong, every filter (Flate, LZW with early change, ASCIIHex, ASCII85, RunLength, PNG and TIFF predictors), the standard security handler from RC4-40 to AES-256, content streams and inline images, the page tree with inherited attributes โ and a writer that produces the same bytes twice. Of 118 863 real PDFs, 118 833 open; the thirty that do not are 27 PNGs named .pdf, one PostScript file and two truncated past recovery.
repository ยท pkg.go.dev
The verbs, and the pdfops command โ 49 of them. Merge, select, delete, reverse, move, rotate, crop, resize, split, n-up, booklet, poster, divide, duplex, overlay, blank pages, watermarks, page numbers, Bates stamps, page labels, layers, text colour, sanitize, flatten, compress, encrypt, decrypt, permissions, repair, attachments, forms โ and reading a page back as text, pictures, tables (CSV, JSON or Markdown) or a whole document in Markdown. Links and bookmarks are carried over and pointed at the pages they became. Every verb is measured on the whole corpus: 118 833 files compressed and read back page for page identical, 35.2 GB down to 33.6 GB.
repository ยท pkg.go.dev
Turns a page into pixels. The transform stack, every painting operator, both winding rules, strokes with caps/joins/miter/dashes, clipping, every colour space, transparency, form XObjects; images at every depth with soft and stencil masks; text from TrueType, OpenType, bare CFF, PostScript Type 1, composite and Type 3 fonts; PDF functions of all four kinds, all seven shadings โ axial, radial, function-based, and the four mesh kinds, triangles and Coons and tensor patches โ and shading and tiling patterns, placed in the space of the form that names them. Rasterises with go-gfx and reads outlines with go-opentype. Builds for js/wasm.
repository ยท pkg.go.dev
What a document says about a font โ not the outlines, which are the program’s business. Which codes a string holds, how wide each is, what each is called, and what text each stands for, through /ToUnicode and the encodings. It refuses one guess: a symbolic font read through an assumed encoding gives the wrong letter with nothing to say so. The glyph-name table is checked against the documents themselves โ 63 515 names, 99.31% agreement.
repository ยท pkg.go.dev
Pictures into a PDF, and a PDF back into pictures. Reads PNG, JPEG, GIF, BMP, TIFF and WebP; writes all but WebP โ which it refuses by name, because there is no pure-Go encoder and writing a PNG under a .webp name would be worse than saying no. The content decides a format, never the file’s name. Only the DPI says which page a picture is: 2480ร3508 is A4 at 300 and a page a metre tall at 72. Fitting onto paper uses one scale for both axes and only ever shrinks.
repository ยท pkg.go.dev
Reads a page back: the text with where each piece of it sits, the pictures with the box each covers, and the grids its text lines up into. A page holds instructions for drawing glyphs, not text โ so where the document says nothing about what they mean, this says so rather than guessing. A column boundary is a stretch of page every row leaves empty, and three things that look like columns are not: a bullet, a column nothing was drawn in, and a page number. On one 213-page document those three took the count from 588 tables to 40, which are the real ones; a prose report in the same run reports none. Over the whole corpus: 121 946 pages, 34 million characters, 1.89% of runs that nothing in the document could name, 300 685 pictures located, no panics.
repository ยท pkg.go.dev
A PDF read back as a document rather than as text โ headings, paragraphs, lists and tables, into the richdoc model, which gets Markdown, reST and HTML out of a PDF through code the fleet already has. A page has no headings: it has glyphs at places, and everything above that is an inference. A heading is text set larger than the body and rare with it โ measured over six real documents, heading sizes hold 0.01% to 5.76% of the characters and a second body size holds a third, and taking “larger” alone gave a nine-page report 131 headings of which 130 were prose. What it will not read is published too: ruled lines, columns of a multi-column layout, and footnotes.
repository ยท pkg.go.dev
A PDF several people edit at once. What is shared is not the file โ merging two piles of bytes cannot be done โ but the plan: which pages, from which files, in which order, turned and cropped how, with which bookmarks over them. A list, a tree and a handful of fields, which a CRDT merges without asking anybody. Checked with 25 editors making random edits for 40 rounds, merged in a random order, all agreeing on the same document.
repository ยท pkg.go.dev
Read, fill and draw an AcroForm โ the boxes somebody types into, the squares they tick, the lists they choose from. A field’s value is not what gets drawn: what gets drawn is a little content stream beside it, so a reader that fills a field and does not rewrite that stream leaves the page blank. An AcroForm dictionary with an empty field list is not a form โ 561 of the 118 833 figure-corpus files are exactly that, left behind by a producer. Builds for js/wasm.
repository ยท pkg.go.dev
The form inside a PDF whose pages are blank. Of 2 240 real government forms, 560 carry an XFA package and 546 are static โ a second, proprietary copy of a form already drawn on the pages, which forms fills without help. The other fourteen are dynamic: their pages hold a panel reading Please wait… your PDF viewer may not be able to display this type of document, and the document exists only as XML. Adobe removed the format from PDF 2.0, and no browser lays one out.
repository ยท pkg.go.dev
Static HTML to VECTOR PDF, zero C. No headless browser and no screenshot-then-slice: it drives go-webengine’s own layout tree straight into pdfkit’s text, rect and stroke calls, so the text in the PDF is real text โ selectable, searchable, small โ rather than a picture of text.
repository ยท pkg.go.dev
The other direction: reconstruct LaTeX source from a PDF. A PDF that came from TeX does not contain a document; it contains the marks TeX made putting one on paper โ glyphs at absolute positions, from fonts whose names are the only surviving record of what the author asked for. Reconstruct gives back the .tex, and writes out the pictures its includegraphics commands name.
repository ยท pkg.go.dev
Where all of the above is judged by implementations that are not ours, over corpora of real PDFs. A file our own reader reads back perfectly can draw nothing anywhere else โ that has happened here: a rebuilt cross-reference stream our reader was delighted with, and macOS drew a blank page. So these tools ask poppler rather than asking ourselves. A figure is only as honest as the population it came from, so the corpora are chosen and stated rather than collected.
repository ยท pkg.go.dev
A PDF workbench that runs in a browser tab and nowhere else. Open a file, turn its pages, rotate one, drop one, lay it out two to a sheet, write across it, save it back out โ and none of it leaves the machine, because there is nowhere for it to go. The whole tool is one wasm binary the browser downloads once and a service worker then keeps. Driven in CI by a real Chrome over the DevTools protocol, reading the canvas pixels back.
repository ยท pkg.go.dev
The document builder: pages, vector graphics, and text set in embedded, subsetted fonts. TrueType and OpenType/CFF embed as Type0 (Identity-H) composite fonts with a /ToUnicode CMap; JPEG and raster images place directly; a widget bridge prints a go-widgets tree onto a page, rasterised or as selectable vector text. With the zero Options the output has no timestamps and a content-derived /ID, so identical inputs produce byte-identical PDFs.
repository ยท pkg.go.dev