pdfw

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 5, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package pdfw writes PDF files: indirect objects, streams, the cross reference table, and the content stream operators a printout's marks need.

It is a writer and nothing else. It knows no marks, no layout and no fonts beyond embedding the bytes it is handed, so the mapping from a printout to a page is one level up, in package pdf.

Index

Constants

View Source
const Bezier = 0.5522847498

Bezier is the circle approximation constant: the control point offset, as a fraction of the radius, that makes a cubic segment match a quarter circle to within a quarter of a per mille.

View Source
const Version = "1.7"

Version is the PDF version the writer claims.

1.7 covers everything here; nothing emitted needs a later one.

Variables

This section is empty.

Functions

func ASCIIString

func ASCIIString(text string) string

ASCIIString formats a string that is not shown to a person and carries no encoding mark: a URI, a destination name.

func Date

func Date(when time.Time) string

Date formats a timestamp as PDF spells one.

func Num

func Num(value float64) string

Num formats a length for a PDF file: at most three decimals, which is the printout's own precision, with no trailing zeros and no exponent.

func Ref

func Ref(num int) string

Ref formats an indirect reference.

func TextString

func TextString(text string) string

TextString formats a string for a field a reader shows to a person -- a title, an outline entry, a link caption.

Printable ASCII goes out as a literal string; anything else as UTF-16BE with a byte order mark, which is the only encoding PDF defines for text outside PDFDocEncoding.

Types

type Content

type Content struct {
	// Height is the page height, the axis the flip turns around.
	Height float64
	// contains filtered or unexported fields
}

Content builds one page's content stream.

Callers work in the printout's coordinates -- origin top left, Y down -- and Content flips Y as it writes each number. The flip is per coordinate rather than a page-level matrix because a matrix that mirrors the page mirrors the glyphs with it.

func NewContent

func NewContent(height float64) *Content

NewContent starts a content stream for a page of a height.

func (*Content) BeginText

func (con *Content) BeginText()

BeginText opens a text object.

func (*Content) Bytes

func (con *Content) Bytes() []byte

Bytes returns the stream written so far.

func (*Content) Clip

func (con *Content) Clip()

Clip intersects the clipping path with the current path and ends it.

func (*Content) CurveTo

func (con *Content) CurveTo(left1, top1, left2, top2, left3, top3 float64)

CurveTo appends a cubic segment.

func (*Content) Dash

func (con *Content) Dash(pattern []float64)

Dash sets a dash pattern in points. An empty pattern is a solid line.

func (*Content) EndText

func (con *Content) EndText()

EndText closes it.

func (*Content) Fill

func (con *Content) Fill()

Fill paints its interior.

func (*Content) FillColor

func (con *Content) FillColor(red, green, blue float64)

FillColor sets the non-stroking colour, which paints both fills and glyphs.

func (*Content) FillStroke

func (con *Content) FillStroke()

FillStroke paints both, the fill first.

func (*Content) Font

func (con *Content) Font(name string, size float64)

Font selects a font resource at a size.

func (*Content) Len

func (con *Content) Len() int

Len is the number of bytes written, which tells an empty page from one that drew something.

func (*Content) LineTo

func (con *Content) LineTo(left, top float64)

LineTo extends it.

func (*Content) LineWidth

func (con *Content) LineWidth(width float64)

LineWidth sets the stroke width.

Zero is a hairline, which PDF defines as the thinnest line the output device can render, so it is passed through rather than turned into a width of our choosing.

func (*Content) Matrix

func (con *Content) Matrix(scaleX, scaleY, left, top float64)

Matrix concatenates a transformation matrix, its translation given in top-down coordinates: the matrix maps the unit square onto a box whose top-left corner is at left, top.

func (*Content) MoveTo

func (con *Content) MoveTo(left, top float64)

MoveTo starts a subpath.

func (*Content) Rect

func (con *Content) Rect(left, top, width, height float64)

Rect appends a rectangle subpath, given its top-left corner.

func (*Content) Restore

func (con *Content) Restore()

Restore pops it.

func (*Content) RoundedRect

func (con *Content) RoundedRect(left, top, width, height, radius float64)

RoundedRect appends a rectangle with rounded corners. A radius larger than half the shorter side is clamped, so a very round small box stays a box rather than turning inside out.

func (*Content) Save

func (con *Content) Save()

Save pushes the graphics state.

func (*Content) ShowGlyphs

func (con *Content) ShowGlyphs(glyphs []uint16)

ShowGlyphs draws a run of glyphs, given as glyph indices in the embedded subset, which Identity-H encoding writes as two bytes each.

func (*Content) Stroke

func (con *Content) Stroke()

Stroke paints the current path's outline.

func (*Content) StrokeColor

func (con *Content) StrokeColor(red, green, blue float64)

StrokeColor sets the stroking colour from components in 0..1.

func (*Content) TextOffset

func (con *Content) TextOffset(dx, dy float64)

TextOffset moves the line start by a displacement.

This is how the segments of a justified line are placed: each offset is exact, so a segment's position does not depend on the glyph advances before it.

func (*Content) TextStart

func (con *Content) TextStart(left, baseline float64)

TextStart places the first line of a text object by its baseline.

func (*Content) XObject

func (con *Content) XObject(name string)

XObject draws a named external object, an image here.

type Doc

type Doc struct {
	// Compress applies FlateDecode to content and font streams.
	// Off makes the output readable, which is what a failing test wants.
	Compress bool
	// contains filtered or unexported fields
}

Doc collects indirect objects and writes the file around them.

Object numbers are handed out by Alloc and written in any order, so a page can name its content stream before the stream exists. Output is a pure function of what was written: no timestamps of its own, no map iteration, so the same document twice is the same bytes twice.

func New

func New() *Doc

New starts a document.

func (*Doc) Alloc

func (doc *Doc) Alloc() int

Alloc reserves an object number.

func (*Doc) Finish

func (doc *Doc) Finish(root, info int) []byte

Finish appends the cross reference table and the trailer, and returns the whole file.

func (*Doc) Object

func (doc *Doc) Object(num int, body string)

Object writes a reserved object number's body.

func (*Doc) RawStream

func (doc *Doc) RawStream(num int, extra string, data []byte)

RawStream writes a stream whose data is already filtered, so the caller supplies the Filter entry itself. A JPEG passes through this way, keeping its own compression.

func (*Doc) Stream

func (doc *Doc) Stream(num int, extra string, data []byte)

Stream writes a stream object.

extra holds the dictionary entries other than Length and Filter, without the enclosing angle brackets.

func (*Doc) WriteFont

func (doc *Doc) WriteFont(embedded *Embedded) (int, error)

WriteFont writes a font's five objects and returns the number of the Type0 dictionary, which is what a page's resource dictionary names.

func (*Doc) WriteImage

func (doc *Doc) WriteImage(pic *Picture) int

WriteImage writes an image XObject, and its soft mask when it has one, returning the number of the image object.

type Embedded

type Embedded struct {
	Program *sfnt.Font
	Glyphs  []uint16
	// Advances are the glyphs' advance widths in font units,
	// parallel to Glyphs. They are supplied rather than read
	// back out of the program so that the widths a reader
	// advances the pen by are the widths the engine measured.
	Advances []float64
	// Runes maps a subset glyph index to the characters it stands for,
	// which is what makes the text selectable, searchable, and readable
	// back out of the file.
	Runes map[uint16][]rune

	Italic bool
}

Embedded is one font as it will appear in the file: a font program, the glyphs the document actually uses, and how a reader is to read them back.

Glyphs holds original glyph indices, and a glyph's position in the slice is its index in the embedded subset, which under Identity-H encoding is also the two-byte code a content stream shows. Position 0 must be glyph 0, the empty box a font draws for a character it lacks.

type Picture

type Picture struct {
	Width, Height int
	// ColorSpace is a PDF name without its slash: DeviceRGB or DeviceGray.
	ColorSpace string
	// Filter is the PDF filter the samples already carry, empty
	// when they are raw and the writer is free to compress them.
	Filter string
	Data   []byte
	// Alpha holds one grey sample per pixel, absent for an opaque image.
	Alpha []byte
}

Picture is an image ready to become an XObject: samples, the colour space they are in, and a soft mask when the source had transparency.

func DecodePicture

func DecodePicture(raw []byte) (*Picture, error)

DecodePicture turns an image file into samples a PDF can carry.

A JPEG whose own compression a PDF can read is passed through untouched, so a photograph does not grow twentyfold on the way into the document. Everything else is decoded and re-encoded, which is the simple road and correct for every format the format admits.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL