Skip to content
Jennifer Programming Language

pdf API reference

Generate PDF documents - text, lines, rectangles - the way html / label generate their formats. Build a Document of Pages with value-semantic builders, then render() writes the PDF object / xref structure by hand (no stdlib PDF) as bytes. Content streams are FlateDecode-compressed via compress. Two font paths: the standard-14 Type1 fonts (Helvetica / Times / Courier families + Symbol / ZapfDingbats) via text, and embedded TrueType fonts via loadFont / addFont / textUnicode - a Type0 / CIDFontType2 composite (Identity-H) with an embedded FontFile2 and a ToUnicode map, so any script the font covers (accented Latin, Greek, Cyrillic, CJK, ...) renders and stays selectable. Raster images embed as image XObjects via loadImage / addImage / drawImage - PNG (greyscale / RGB / palette, plus 8-bit alpha as a soft mask) and JPEG (DCTDecode). Text layout - measureText width measurement (standard-14 AFM metrics + embedded-font advances), wrapText word-wrap, and textBlock wrapped / aligned paragraphs (left / right / center / justify) - flows text into a column. Object numbers are assigned dynamically. Pure Jennifer (over the font module); both binaries.

Coordinates are in PDF points (1/72 inch), origin bottom-left, y upward. Common page sizes: US Letter 612 x 792, A4 595 x 842. Colours are 0-255 RGB.

Import with import "pdf.j" as pdf;. See the pdf guide for prose and examples.

Functions

pdf.addFont(doc as Document, lf as LoadedFont)

A copy of the document with an embedded font registered, so render writes its font program and dictionaries.

Parameters

  • doc {Document} - the document
  • lf {LoadedFont} - the loaded font (from loadFont)

Returns {Document} - a fresh document with the font registered

pdf.addImage(doc as Document, img as Image)

A copy of the document with an embedded image registered, so render writes its image XObject. Draw it on a page with drawImage.

Parameters

  • doc {Document} - the document
  • img {Image} - the loaded image (from loadImage)

Returns {Document} - a fresh document with the image registered

pdf.addPage(doc as Document, pg as Page)

A copy of the document with a page appended.

Parameters

  • doc {Document} - the document
  • pg {Page} - the page to add

Returns {Document} - a fresh document with the page appended

pdf.bookmark(doc as Document, page as int, y as int, title as string, level as int)

A copy of the document with one outline (bookmark) entry appended (value-semantic). Entries are nested by level in the order added: a level-2 entry becomes a child of the most recent level-1, and so on. The destination scrolls page page (0-based) so that y (PDF points, origin bottom-left) is at the top of the view. With any outline present, the viewer opens showing the bookmark panel.

Parameters

  • doc {Document} - the document
  • page {int} - the 0-based index of the destination page
  • y {int} - the destination y in PDF points
  • title {string} - the bookmark label
  • level {int} - the nesting level (>= 1)

Returns {Document} - a copy with the entry appended

pdf.color(pg as Page, red as int, green as int, blue as int)

Set the fill and stroke colour (0-255 RGB) for subsequent drawing on the page.

Parameters

  • pg {Page} - the page
  • red {int} - the red component 0-255
  • green {int} - the green component 0-255
  • blue {int} - the blue component 0-255

Returns {Page} - a fresh page with the colour set

pdf.document()

An empty document. The Producer metadata defaults to "Jennifer pdf"; everything else is unset (no CreationDate is stamped, so output stays deterministic - set one explicitly with info + pdfDate if you want it).

Returns {Document} - the document

pdf.drawImage(pg as Page, img as Image, x as int, y as int, width as int, height as int)

Draw a registered image scaled into the rectangle at (x, y) of the given width and height (points). The image keeps no aspect ratio of its own - it fills the box - so pass a width / height in the image's own proportion to avoid stretching. addImage the image into the document first so the resource name resolves.

Parameters

  • pg {Page} - the page
  • img {Image} - the image (from loadImage)
  • x {int} - the lower-left x in points
  • y {int} - the lower-left y in points
  • width {int} - the drawn width in points
  • height {int} - the drawn height in points

Returns {Page} - a fresh page with the image drawn

pdf.foldLine(font as string, size as int, text as string, maxWidth as int)

Hard-fold one line so every piece fits maxWidth (points). Breaks at the last space or seam punctuation before the overflow, or mid-token when there is none (a bare URL, a slash-joined identifier). Unlike wrapText, it does not reflow on every space - it only breaks where a line would otherwise run past the box - so it is the right tool for a code line or an unbreakable token that must stay on the page. A single character wider than maxWidth is emitted alone.

Parameters

  • font {string} - the standard-14 font
  • size {int} - the point size
  • text {string} - the line to fold (no embedded newlines)
  • maxWidth {int} - the target width in points

Returns {list of string} - the fitted pieces (at least one)

pdf.getCurrentPageNr(doc as Document)

The 1-based number of the page currently being built - the next page to be added, i.e. getTotalPages(doc) + 1. Use it while filling a page (before addPage) to label it.

Parameters

  • doc {Document} - the document

Returns {int} - the current page number

pdf.getTotalPages(doc as Document)

The total number of pages added to the document (the value {pages} expands to).

Parameters

  • doc {Document} - the document

Returns {int} - the page count

pdf.info(doc as Document, key as string, value as string)

A copy of the document with one metadata field set (value-semantic). key is a PDF Info key - "Title", "Author", "Subject", "Keywords", "Creator", "Producer", "CreationDate", "ModDate" (or any custom key).

Parameters

  • doc {Document} - the document
  • key {string} - the Info-dictionary key
  • value {string} - the value

Returns {Document} - a fresh document with the metadata set

pdf.line(pg as Page, fromX as int, fromY as int, toX as int, toY as int)

Draw a straight line from (fromX, fromY) to (toX, toY).

Parameters

  • pg {Page} - the page
  • fromX {int} - the start x
  • fromY {int} - the start y
  • toX {int} - the end x
  • toY {int} - the end y

Returns {Page} - a fresh page with the line added

pdf.link(pg as Page, x as int, y as int, width as int, height as int, uri as string)

Add a link annotation: a clickable rectangle (lower-left x, y, plus width / height, in PDF points) that opens uri. The border is invisible, so place it over text drawn with text (measure the text width with measureText) to make that text a hyperlink - a footer backlink, a citation, a URL in prose.

Parameters

  • pg {Page} - the page
  • x {int} - lower-left x of the clickable rectangle
  • y {int} - lower-left y of the clickable rectangle
  • width {int} - rectangle width in points
  • height {int} - rectangle height in points
  • uri {string} - the URI the link opens

Returns {Page} - the page with the link recorded

pdf.loadFont(name as string, data as bytes)

Load an embeddable font from its bytes, under a resource name used to select it in textUnicode. The font is embedded (and its Unicode text made selectable) when the document renders.

Parameters

  • name {string} - the resource name (e.g. "Body"; letters / digits)
  • data {bytes} - the TrueType (.ttf) font file

Returns {LoadedFont} - the loaded font

pdf.loadImage(name as string, data as bytes)

Load a raster image (PNG or JPEG) from its bytes, under a resource name used to select it in drawImage. The format is detected from the file signature. PNG: non-interlaced greyscale / RGB / palette (embedded directly with a FlateDecode predictor) and 8-bit greyscale+alpha / RGBA (decoded to a colour stream plus an alpha soft mask). JPEG: baseline / progressive greyscale / RGB / CMYK, embedded as-is via DCTDecode.

Parameters

  • name {string} - the resource name (e.g. "Logo"; letters / digits)
  • data {bytes} - the PNG or JPEG file

Returns {Image} - the loaded image

Throws

  • {Error} - kind "pdf" if the data is not a supported PNG / JPEG

pdf.measureText(font as string, size as int, str as string)

Measure the rendered width (in points) of a string in a standard-14 font at a point size, using the Adobe Core-14 AFM metrics. A character outside WinAnsi, or a Symbol / ZapfDingbats font, throws.

Parameters

  • font {string} - a standard-14 base font name
  • size {int} - the font size in points
  • str {string} - the text to measure

Returns {float} - the width in points

Throws

  • {Error} - kind "pdf" for an unknown / metric-less font

pdf.measureTextUnicode(lf as LoadedFont, size as int, str as string)

Measure the rendered width (in points) of a string in an embedded font at a point size, using the font's own glyph advances.

Parameters

  • lf {LoadedFont} - the embedded font
  • size {int} - the font size in points
  • str {string} - the text to measure

Returns {float} - the width in points

pdf.page(width as int, height as int)

A blank page of the given size in points (e.g. page(612, 792) for Letter, page(595, 842) for A4).

Parameters

  • width {int} - the page width in points
  • height {int} - the page height in points

Returns {Page} - the page

pdf.pageLabel()

A blank page label (empty slots, Helvetica 9pt, 36-point margin, no border, black). Copy it and set slots / options, then attach with setHeader / setFooter.

Returns {PageLabel} - the default label

pdf.pdfDate(t as time.Time)

Format an instant as a PDF date string (D:YYYYMMDDHHmmSS+HH'mm'), for use as a CreationDate / ModDate value. Passing a time is explicit, so it does not make render non-deterministic on its own.

Parameters

  • t {time.Time} - the instant

Returns {string} - the PDF date string

pdf.rect(pg as Page, x as int, y as int, width as int, height as int, filled as bool)

Draw a rectangle at (x, y) of the given size. filled fills it; otherwise it is stroked (outline only).

Parameters

  • pg {Page} - the page
  • x {int} - the lower-left x
  • y {int} - the lower-left y
  • width {int} - the width in points
  • height {int} - the height in points
  • filled {bool} - true to fill, false to stroke

Returns {Page} - a fresh page with the rectangle added

pdf.render(doc as Document)

Render the document to PDF bytes (PDF 1.7). Any running header / footer is drawn onto every page first. Content streams are FlateDecode-compressed; standard-14 fonts become shared Type1 objects and each embedded font a Type0 / CIDFontType2 with an embedded FontFile2 and a ToUnicode map. Registered images become image XObjects (with a soft-mask XObject when they carry alpha). An outline (bookmarks) is emitted when the document has any, with the catalog set to open the bookmark panel. Objects are numbered dynamically, so any mix of pages, fonts, images, and resources references correctly.

Parameters

  • doc {Document} - the document to render

Returns {bytes} - the PDF file contents

pdf.setFooter(doc as Document, label as PageLabel)

Attach a running footer, drawn on every page when the document renders.

Parameters

  • doc {Document} - the document
  • label {PageLabel} - the footer spec

Returns {Document} - the document with the footer set

pdf.setHeader(doc as Document, label as PageLabel)

Attach a running header, drawn on every page when the document renders.

Parameters

  • doc {Document} - the document
  • label {PageLabel} - the header spec

Returns {Document} - the document with the header set

pdf.text(pg as Page, x as int, y as int, font as string, size as int, str as string)

Draw a line of text at (x, y) in the given standard-14 font and point size.

Parameters

  • pg {Page} - the page
  • x {int} - the x position (points from the left)
  • y {int} - the y position (points from the bottom)
  • font {string} - a standard-14 base font name (e.g. "Helvetica")
  • size {int} - the font size in points
  • str {string} - the text to draw

Returns {Page} - a fresh page with the text added

Throws

  • {Error} - kind "pdf" if the font is not a standard-14 name

pdf.textBlock(pg as Page, x as int, y as int, width as int, font as string, size as int, leading as int, str as string, align as string)

Flow standard-14 text into a column: word-wrap str to width points and draw each line, the first line's baseline at (x, y) and each subsequent line leading points lower. align is "left" / "right" / "center" / "justify" (justify pads inter-word gaps on every line but the last of each paragraph). The drawn block is len(wrapText(...)) * leading points tall.

Parameters

  • pg {Page} - the page
  • x {int} - the column's left x in points
  • y {int} - the first line's baseline y in points
  • width {int} - the column width in points
  • font {string} - a standard-14 base font name
  • size {int} - the font size in points
  • leading {int} - the line-to-line spacing in points
  • str {string} - the text (newlines are hard breaks)
  • align {string} - "left" / "right" / "center" / "justify"

Returns {Page} - a fresh page with the text block drawn

Throws

  • {Error} - kind "pdf" for an unknown align or font

pdf.textBlockUnicode(pg as Page, x as int, y as int, width as int, lf as LoadedFont, size as int, leading as int, str as string, align as string)

Flow embedded-font (Unicode) text into a column - textBlock for a font from loadFont / addFont. Same wrapping / alignment / leading behaviour.

Parameters

  • pg {Page} - the page
  • x {int} - the column's left x in points
  • y {int} - the first line's baseline y in points
  • width {int} - the column width in points
  • lf {LoadedFont} - the embedded font
  • size {int} - the font size in points
  • leading {int} - the line-to-line spacing in points
  • str {string} - the text (newlines are hard breaks)
  • align {string} - "left" / "right" / "center" / "justify"

Returns {Page} - a fresh page with the text block drawn

Throws

  • {Error} - kind "pdf" for an unknown align

pdf.textUnicode(pg as Page, x as int, y as int, lf as LoadedFont, size as int, str as string)

Draw Unicode text at (x, y) in an embedded font (from loadFont + addFont) at the given point size. Each character maps through the font's cmap to a glyph, so any script the font covers - including CJK - renders and stays selectable / copyable in a viewer.

Parameters

  • pg {Page} - the page
  • x {int} - the x position (points from the left)
  • y {int} - the y position (points from the bottom)
  • lf {LoadedFont} - the embedded font
  • size {int} - the font size in points
  • str {string} - the text to draw

Returns {Page} - a fresh page with the text added

pdf.toWinAnsi(s as string, replacement as string)

Return s with every character the standard-14 fonts cannot encode (outside WinAnsi / windows-1252) replaced by replacement ("" drops it). A clean string (the common case) is returned unchanged after a single whole-string check, so the per-character path runs only when there is something to replace. This lets a caller keep one out-of-range glyph from aborting a whole render.

Parameters

  • s {string} - the text
  • replacement {string} - the substitute for an un-encodable character

Returns {string} - the WinAnsi-safe text

pdf.wrapText(font as string, size as int, str as string, maxWidth as int)

Word-wrap a standard-14 string to a maximum line width (points), returning the lines. Existing newlines are honoured as hard breaks; runs of spaces collapse. A word-wrapped line still wider than the box (an unbreakable token) is hard-folded with foldLine, so no output line runs past maxWidth.

Parameters

  • font {string} - a standard-14 base font name
  • size {int} - the font size in points
  • str {string} - the text to wrap
  • maxWidth {int} - the maximum line width in points

Returns {list of string} - the wrapped lines

pdf.wrapTextUnicode(lf as LoadedFont, size as int, str as string, maxWidth as int)

Word-wrap an embedded-font string to a maximum line width (points).

Parameters

  • lf {LoadedFont} - the embedded font
  • size {int} - the font size in points
  • str {string} - the text to wrap
  • maxWidth {int} - the maximum line width in points

Returns {list of string} - the wrapped lines

Structs

pdf.Document

A PDF document: an ordered list of pages, the document metadata (the PDF Info dictionary, keyed by PDF key name - "Title", "Author", ...), any embedded fonts registered with addFont, any outline (bookmark) entries, and an optional running header / footer drawn on every page at render time.

FieldTypeDescription
pageslist of Pagethe document's pages
infomap of string to stringthe Info-dictionary metadata
embeddedlist of LoadedFontthe embedded fonts
imageslist of Imagethe embedded raster images
outlinelist of OutlineEntrythe outline / bookmark entries, in document order
headerPageLabelthe running header (drawn when headerOn)
footerPageLabelthe running footer (drawn when footerOn)
headerOnboolwhether a header has been set
footerOnboolwhether a footer has been set

pdf.GlyphUse

A record of one glyph used by embedded text: which font, its glyph id, and the Unicode codepoint it came from - collected so render can build the font's width array and ToUnicode map.

FieldTypeDescription
fontstringthe font resource name
gidintthe glyph id
cpintthe source Unicode codepoint

pdf.Image

A loaded raster image (from loadImage), ready to embed as a PDF image XObject and draw with drawImage. Register it in a document with addImage.

FieldTypeDescription
namestringthe resource name (referenced in drawImage)
widthintthe pixel width
heightintthe pixel height
bitsintbits per colour component
colorSpacestringthe PDF colour-space token (e.g. "/DeviceRGB")
filterstringthe stream filter ("DCTDecode" for JPEG, "FlateDecode" for PNG)
predictorint15 when the FlateDecode stream carries PNG predictors, else 0
colorsintcolour components per pixel (for the predictor DecodeParms)
decodestringan optional /Decode array token (Adobe CMYK JPEG), else ""
databytesthe image stream bytes
smaskbytesthe soft-mask (alpha) stream, empty when opaque
hasSmaskboolwhether the image carries an alpha soft mask

pdf.LinkAnnot

A link annotation: a clickable rectangle on a page that opens a URI. The rect is given in PDF points by its lower-left corner and its size; the border is drawn invisibly, so only the underlying text (or graphic) shows.

FieldTypeDescription
xintlower-left x of the clickable rectangle
yintlower-left y of the clickable rectangle
widthintrectangle width in points
heightintrectangle height in points
uristringthe URI the link opens

pdf.LoadedFont

A loaded, embeddable font: a resource name (referenced in textUnicode) and the parsed font.Font. Register it in a document with addFont.

FieldTypeDescription
namestringthe resource name (e.g. "Body")
ffont.Fontthe parsed font

pdf.OutlineEntry

One outline (bookmark) entry: a title that jumps to a position on a page, plus the heading level that nests it under the outline tree. Built with bookmark.

FieldTypeDescription
titlestringthe bookmark label
pageintthe 0-based page index the bookmark points at
yintthe destination y coordinate in PDF points (origin bottom-left)
levelintthe nesting level (1 = top; a level-2 entry nests under the last level-1)

pdf.Page

A single page: its size (points), its accumulated content-stream operators, and its link annotations.

FieldTypeDescription
widthintthe page width in points
heightintthe page height in points
contentstringthe content-stream operators built so far
fontslist of stringthe distinct standard-14 fonts referenced on this page
glyphUseslist of GlyphUseembedded-font glyphs drawn on this page
annotslist of LinkAnnotthe page's link annotations

pdf.PageLabel

A running header or footer, drawn on every page at render time. Its three text slots are left- / centre- / right-aligned (alignment measured with the font's own metrics), and each may contain the placeholders %page% (the 1-based page number) and %pages% (the total page count), filled in per page - so a footer "sample.pdf" / "" / "%page%/%pages%" reads sample.pdf ... 13/108. The placeholders are percent-delimited (not braces) so they do not collide with Jennifer's own {expr} string interpolation. margin is the distance from the page edge to the text on every side. With border on, a thin rule is drawn under a header / over a footer.

FieldTypeDescription
leftstringleft-aligned slot (may use %page% / %pages%)
centerstringcentre-aligned slot
rightstringright-aligned slot
fontstringa standard-14 font name
sizeintthe point size
marginintdistance from the page edge, in points
borderbooldraw a separating rule
redinttext / rule colour red 0-255
greeninttext / rule colour green 0-255
blueinttext / rule colour blue 0-255
leftUristringif set, makes the left slot a link to this URI ("" = none)
centerUristringif set, makes the centre slot a link to this URI ("" = none)
rightUristringif set, makes the right slot a link to this URI ("" = none)