Skip to content

Latest commit

 

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

render

CI Go Reference Go Report Card License: BSD-3-Clause Coverage

Turns a page of a PDF into pixels, in pure Go with no C anywhere.

It reads with reader, takes what a document says about its fonts from pdffont, rasterises with go-gfx/gfx, and — where there is text — shapes and outlines it with go-opentype. Nothing else: this builds for GOOS=js/wasm and every architecture the fleet targets, which is what lets a PDF be shown in a browser tab with nothing on the far end.

What it draws

The graphics half of the format: the transform stack, path construction and every one of the ten painting operators, filling under both winding rules, stroking with the caps, joins, miter limit and dash pattern the graphics state carries, clipping — including clips that intersect and are let go again with Q — the device, calibrated, profile-based, indexed, separation and pattern colour spaces, constant transparency, and form XObjects with their own matrix, bounding box and resources.

Images too: XObjects and inline images, at every bit depth the format has, in every colour space, with a /Decode array, as one-bit stencils painted in the colour in force, and with either kind of transparency — a soft mask of levels or a stencil of what to leave out. A JPEG is decoded by the standard library; a format nothing here reads is left undrawn rather than drawn wrong.

Text: the whole text state and every positioning and showing operator, with glyphs taken from an embedded TrueType or OpenType font, from a PostScript Type 1 program, from a bare CFF one, from a composite font addressed by character identifier, or — for a Type 3 font, whose glyphs are little content streams — by running them. A simple font is addressed by the name its encoding gives a code, and falls back on the program's own built-in encoding when the document says nothing. A font whose program the file does not carry at all — two pages of the corpus in five — is drawn in a stand-in: Arimo, Tinos and Cousine are metric-compatible with Helvetica, Times and Courier, so the text comes out the width it was meant to be even where the document gives no widths of its own. A bold is made by stroking the outline as well as filling it and an italic by leaning it over, since only one weight of each stand-in is carried. Symbol and the dingbats are left alone: no face here has their glyphs, and something is not better than nothing when the something is the wrong alphabet.

Gradients and patterns: the axial and radial shadings that carry nearly every gradient anyone draws, painted on their own with sh or used as a fill or a stroke; tiling patterns, coloured and uncoloured, run once per cell and clipped to the shape; and the four kinds of function the format has — a sampled grid, an exponential curve, several of them stitched end to end, and a little PostScript program — which are also what a Separation or DeviceN colour space's tint transform is written in.

And the mesh shadings, all four of them, which is how a plotting tool writes a surface: free-form and lattice-form triangles, each corner its own colour, and Coons and tensor patches, whose four sides are curves. A patch is drawn by cutting it into a grid of little quadrilaterals — the inside of a Coons patch follows from its twelve boundary points, and a tensor patch says four more — and every triangle is filled by mixing the colours at its corners across it. A patch may carry on from the one before it, sharing an edge and two of its colours, which is how a surface is written without repeating a single point.

A pattern is placed in the space of the content that names it. That is the page's own space at the top level, and inside a form it is the form's: its matrix and the transform that drew it both count. Nearly every figure a plotting tool writes is a form, so a pattern that stayed at the page's origin would miss the shape it was asked to fill by the width of a page.

How it is checked

By writing a PDF whose geometry is known and looking at the pixels that come out: a rectangle from (10,10) to (40,40) on a hundred-point page has to be ink at (25,75) in the image and paper at (25,55), which is what says the page's coordinates — which count up from the bottom left — were mapped the right way up. Rotation, a media box that does not start at the origin, the crop box winning over the media box, every colour space, both winding rules, clipping, transparency and forms are all checked the same way.

Then on the corpus, for robustness rather than correctness: 4 108 pages drawn from 3 999 real files with no panics and no failures. 6 of them come out blank, which is the honest count of pages carrying nothing this wave understands yet — it was 373 before images, 31 before text, and 26 before Type 1 and bare CFF font programs.

And, when what is underneath changes, on the corpus again — by hashing every page's pixels before and after rather than by watching the exit status. That is how the two defects behind gfx v0.10.0 and opentype v0.7.0 were measured: a stroke assembled out of overlapping pieces came out at about half the colour it was asked for, and a CID font that carried no character map was refused outright, taking every glyph in it off the page. 3 520 of 4 057 pages changed; 1 705 of them gained ink, one of them twice over.

Testing

go test -covermode=set ./...

CI gates on exact 100% statement coverage, go vet, and a cross-compile across linux/{amd64,arm64,riscv64,loong64,ppc64le,s390x}, js/wasm, darwin/arm64 and windows/amd64.

The rest of the family

reader reads and writes the format · ops is the verbs and the pdfops command · render turns a page into pixels · pdffont is what a document says about a font · extract reads a page back · coedit is a PDF several people edit at once · app is the browser workbench.

Documentation for all of it: https://go-pdfkit.github.io/docs/

License

BSD-3-Clause — see LICENSE. Copyright the go-pdfkit/render authors.

About

Pure-Go (CGO=0) PDF rasteriser: graphics state, paths, images, text and shadings, on go-gfx and go-opentype

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages