Help us shape the future of Go! Take the 2026 Go Developer Survey

pdffont

package module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Oct 4, 2026 License: BSD-3-Clause Imports: 3 Imported by: 0

README

pdffont

CI Go Reference Coverage

The PDF side of a font: not the outlines, which are the font program's business, but everything the document itself says about how a string of bytes is to be read.

Which codes a string holds, how wide each one is, what each is called, and what text each stands for. It is what a renderer needs before it can ask a font program for a glyph, and all an extractor needs to read a page back as words — so neither has to say it twice.

Pure Go, no C, nothing outside reader and the standard library.

What it reads

Simple fonts, addressed one byte at a time through a base encoding and whatever differences the document names on top of it. Composite fonts, addressed by character identifier, with their widths and their map from identifier to glyph. Type 3 fonts, whose glyphs are little drawings and whose widths are in a space of their own.

And /ToUnicode, which is the one thing in a PDF that says what its text actually says. Without it a page can be drawn but not read.

What it refuses to guess

A font that says it is symbolic is addressed through its own character map, and a base encoding is a guess at it — a bad one. A mathematical font puts a capital gamma where the standard encoding puts an inverted exclamation mark, so reading the name gives the wrong letter with nothing to say so.

Such a code is left unread unless the document named it itself, or unless a caller installs Font.SetFallback to say what the embedded program calls it. Reading the program is another package's work; extract does it with go-opentype.

How it is checked

100% of statements, including every branch that handles a dictionary saying something it should not.

And the glyph-name table — which is the one piece of data here, and where a single wrong entry would silently give the wrong letter — is held up against the documents themselves. A font that both names a code and carries a /ToUnicode entry for it states the same fact twice, so the two can be compared. Over 12 000 corpus files: 63 515 names checked, 63 074 agreed — 99.31%. The disagreements are producers whose own maps are wrong (alpha → ↵, ff → !), plus Delta and Omega, which Adobe's list gives as the increment and ohm signs; the Greek letters written here are the same characters by Unicode's own equivalence, and the ones a person searching would type.

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/

Licence

BSD-3-Clause.

Documentation

Overview

Package pdffont is the PDF side of a font: not the outlines, which are the font program's business, but everything the document itself says about how a string of bytes is to be read. Which codes a string holds, how wide each one is, what each is called, and what text each stands for.

It is what a renderer needs before it can ask a font program for a glyph, and all an extractor needs to read a page back as words. Both would otherwise have to say the same things twice.

Index

Constants

This section is empty.

Variables

View Source
var StandardEncoding = [256]string{}/* 149 elements not displayed */

StandardEncoding is Adobe's own, which most Type 1 fonts assume, and what a simple font is read with when it says nothing else.

View Source
var WinAnsiEncoding = [256]string{}/* 218 elements not displayed */

WinAnsiEncoding is the one a file written on Windows assumes, and the one most producers name.

Functions

func NamedEncoding

func NamedEncoding(name reader.Name, fallback [256]string) [256]string

NamedEncoding is the table a name stands for, or the fallback for a name that is not one of them.

func ReadToUnicode

func ReadToUnicode(data []byte) map[int]string

ReadToUnicode decodes a ToUnicode CMap: a little PostScript program whose only meaningful parts are the bfchar and bfrange blocks saying which characters each code stands for.

func RuneOfGlyphName

func RuneOfGlyphName(name string) (rune, bool)

RuneOfGlyphName turns a glyph name into the character it stands for, through the table above or through the two conventions the specification defines for naming a character directly. ok is false for a name that says nothing about which character it is, which a subsetted font's own names often do not.

func TextOfGlyphName added in v0.3.0

func TextOfGlyphName(name string) (string, bool)

TextOfGlyphName turns a glyph name into the text it stands for, which is not always one character: a name may say it is a ligature of several.

Three of the rules here are the ones the Adobe Glyph List lays down for reading a name nobody has listed, and each was costing real text. A name may carry a variant after a full stop — "a.sc" is a small-capital A and is still an A, 7 272 of them in the corpus. A name may be several component names with underscores between them — "f_i" is the fi ligature, and without this "Definition" comes back "Denition", which is not a missing character so much as a misspelt word. And a name may simply be one nobody thought to list.

func TrimText

func TrimText(s string) string

TrimText tidies what a map gives back: the format allows a value to carry the replacement character or nothing at all, and neither is text.

Types

type Font

type Font struct {
	// contains filtered or unexported fields
}

A Font is a font as the document describes it.

func Read

func Read(d *reader.Document, dict reader.Dict) *Font

Read takes what a font dictionary says. It never fails: a dictionary that says nothing useful gives a font that reads its codes one byte at a time and advances by half an em, which is what a reader has to do with one anyway.

func (*Font) CIDToGID

func (f *Font) CIDToGID(cid int) (int, bool)

CIDToGID maps a character identifier to a glyph number for a composite font. ok is false when the font's map does not reach that far.

func (*Font) CharProcs

func (f *Font) CharProcs() reader.Dict

CharProcs are a Type 3 font's glyph drawings, by name.

func (*Font) Chosen

func (f *Font) Chosen(code int) bool

Chosen reports whether the document named this code itself rather than inheriting the name from a base encoding.

func (*Font) Codes

func (f *Font) Codes(s []byte) []int

Codes cuts a string into the codes it holds: one byte at a time for a simple font, two for a composite one, which is what every composite encoding seen in the wild uses.

func (*Font) Descriptor

func (f *Font) Descriptor() reader.Dict

Descriptor is the font descriptor, which is where an embedded program lives.

func (*Font) Dict

func (f *Font) Dict() reader.Dict

Dict is the font dictionary itself, for whatever a caller needs that this does not say.

func (*Font) FontMatrix

func (f *Font) FontMatrix() [6]float64

FontMatrix is how a Type 3 font's glyph space relates to text space. For every other kind it is a thousandth, which is what the format assumes.

func (*Font) GlyphName

func (f *Font) GlyphName(code int) (string, bool)

GlyphName is what the document's encoding calls a code. ok is false for a composite font, which names nothing, and for a code the encoding passes over.

func (*Font) HasWidth added in v0.2.0

func (f *Font) HasWidth(code int) bool

HasWidth reports whether the document said how wide this code is, rather than the width being the fallback Font.Width gives for one it did not.

It matters for a font the document does not carry. One of the fourteen standard faces is written with no widths at all — every reader is expected to know Times and Helvetica and Courier by heart — so a reader drawing a stand-in has to take the advances from the stand-in too. Half an em for every letter reads as a typewriter, which is not what the page says.

func (*Font) Kind

func (f *Font) Kind() Kind

Kind says how this font's codes are read.

func (*Font) Program

func (f *Font) Program() (reader.Name, []byte, bool)

Program is the embedded font program: which key it arrived under, and its bytes. ok is false for a font whose program is not embedded, which is every standard face and many others besides.

func (*Font) SetFallback

func (f *Font) SetFallback(fn func(code int) (string, bool))

SetFallback installs a last resort for codes the document says nothing about: what the embedded font program calls them.

A font that says it is symbolic is addressed through its own character map, and what that map says is the only honest answer for a code the document did not name. Reading the program is another package's work, so a caller that can do it hands the answer in here.

func (*Font) Symbolic

func (f *Font) Symbolic() bool

Symbolic reports a font that says it is addressed through its own character map rather than through an encoding of names.

func (*Font) Text

func (f *Font) Text(code int) (string, bool)

Text is what a code stands for as characters: what the font's ToUnicode map says, or failing that what its glyph name says. ok is false when neither does — a subsetted font naming its glyphs g17 and carrying no map cannot be read back, and saying so is better than guessing.

func (*Font) Type3Resources

func (f *Font) Type3Resources() reader.Dict

Type3Resources are what a Type 3 font's glyph drawings draw with.

func (*Font) Width

func (f *Font) Width(code int) float64

Width is how far the pen moves for one code, in text space — a multiple of the point size, so a width of half means half an em.

type Kind

type Kind int

A Kind says how a font's codes are read.

const (
	// Simple fonts take one byte a code and are addressed by glyph name.
	Simple Kind = iota
	// Composite fonts take a character identifier, usually two bytes wide.
	Composite
	// Type3 fonts draw each glyph by running a little content stream.
	Type3
)

Jump to

Keyboard shortcuts

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