Getting started

You need Go version 1.18 or later.

Let’s start with an empty directory and a new Go module:

go mod init bagtest

and create a file main.go which looks like this:

package main

import (


var (
	str = `In olden times when wishing still helped one, there lived a king whose daughters
	were all beautiful; and the youngest was so beautiful that the sun itself, which
	has seen so much, was astonished whenever it shone in her face.
	Close by the king's castle lay a great dark forest, and under an old lime-tree in the forest
	was a well, and when the day was very warm, the king's child went out into the
	forest and sat down by the side of the cool fountain; and when she was bored she
	took a golden ball, and threw it up on high and caught it; and this ball was her
	favorite plaything.`

func typesetSample() error {
	f, err := frontend.New("sample.pdf")
	if err != nil {
		return err

	f.Doc.Title = "The frog king"

	if f.Doc.DefaultLanguage, err = frontend.GetLanguage("en"); err != nil {
		return err

	// Load a font, define a font family, and add this font to the family.
	ff := f.NewFontFamily("text")
		&frontend.FontSource{Source: "fonts/CrimsonPro-Regular.ttf"},

	// Create a recursive data structure for typesetting initialized with the
	// text from the top (but with space normalized).
	para := frontend.NewText()
	para.Items = []any{strings.Join(strings.Fields(str), " ")}

	// Format the text into a paragraph. Some of these settings (font family and
	// font size) can be part of the typesetting element.
	vlist, _, err := f.FormatParagraph(para, bag.MustSp("125pt"),
	if err != nil {
		return err

	// Output the text and finish the page and the PDF file.
	p := f.Doc.NewPage()
	p.OutputAt(bag.MustSp("1cm"), bag.MustSp("26cm"), vlist)
	if err = f.Doc.Finish(); err != nil {
		return err
	return nil

func main() {
	starttime := time.Now()
	err := typesetSample()
	if err != nil {
	fmt.Println("finished in ", time.Now().Sub(starttime))

Run go mod tidy to let Go download all required libraries and get the font from Then you can run the program by calling go run main.go. You will see output such as:

{"level":"info","ts":1654157162.5800772,"caller":"pdf/pdffont.go:109","msg":"Load font fonts/CrimsonPro-VariableFont_wght.ttf"}
{"level":"info","ts":1654157162.589091,"caller":"pdf/pdffont.go:165","msg":"Write font fonts/CrimsonPro-VariableFont_wght.ttf to PDF"}
{"level":"info","ts":1654157162.5899708,"caller":"document/document.go:671","msg":"Output written to sample.pdf (7715 bytes)"}

The result is a file called sample.pdf which looks like this: