gofpdf

package module
v0.0.0-...-98fe7ea Latest Latest
Warning

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

Go to latest
Published: Jun 18, 2015 License: ISC Imports: 26 Imported by: 1

README

This fork has been created to generate layered PDFs from particular SVG type of files.

Please use original library http://godoc.org/github.com/jung-kurt/gofpdf.

Package gofpdf implements a PDF document generator with high level support for text, drawing and images.

See the documentation for more details.

Documentation

Overview

Package gofpdf implements a PDF document generator with high level support for text, drawing and images.

Features

• Choice of measurement unit, page format and margins

• Page header and footer management

• Automatic page breaks, line breaks, and text justification

• Inclusion of JPEG, PNG, GIF and basic path-only SVG images

• Colors, gradients and alpha channel transparency

• Outline bookmarks

• Internal and external links

• TrueType, Type1 and encoding support

• Page compression

• Lines, Bézier curves, arcs, and ellipses

• Rotation, scaling, skewing, translation, and mirroring

• Clipping

• Document protection

• Layers

gofpdf has no dependencies other than the Go standard library. All tests pass on Linux, Mac and Windows platforms. Like FPDF version 1.7, from which gofpdf is derived, this package does not yet support UTF-8 fonts. However, support is provided to translate UTF-8 runes to code page encodings.

Acknowledgments

This package's code and documentation are closely derived from the FPDF library created by Olivier Plathey, and a number of font and image resources are copied directly from it. Drawing support is adapted from the FPDF geometric figures script by David Hernández Sanz. Transparency support is adapted from the FPDF transparency script by Martin Hall-May. Support for gradients and clipping is adapted from FPDF scripts by Andreas Würmser. Support for outline bookmarks is adapted from Olivier Plathey by Manuel Cornes. Layer support is adapted from Olivier Plathey. Support for transformations is adapted from the FPDF transformation script by Moritz Wagner and Andreas Würmser. PDF protection is adapted from the work of Klemen Vodopivec for the FPDF product. Lawrence Kesteloot provided code to allow an image's extent to be determined prior to placement. Support for vertical alignment within a cell was provided by Stefan Schroeder. Ivan Daniluk generalized the font and image loading code to use the Reader interface while maintaining backward compatibility. Anthony Starks provided code for the Polygon function. Robert Lillack provided the Beziergon function and corrected some naming issues with the internal curve function. Bruno Michel has provided valuable assistance with the code.

The FPDF website is http://www.fpdf.org/.

License

gofpdf is copyrighted by Kurt Jung and is released under the MIT License.

Installation

To install the package on your system, run

go get github.com/jung-kurt/gofpdf

Later, to receive updates, run

go get -u github.com/jung-kurt/gofpdf

Quick Start

The following Go code generates a simple PDF.

pdf := gofpdf.New("P", "mm", "A4", "../font")
pdf.AddPage()
pdf.SetFont("Arial", "B", 16)
pdf.Cell(40, 10, "Hello, world")
pdf.Output(os.Stdout)

See the tutorials in the fpdf_test.go file (shown as examples in this documentation) for more advanced PDF examples.

Errors

If an error occurs in an Fpdf method, an internal error field is set. After this occurs, Fpdf method calls typically return without performing any operations and the error state is retained. This error management scheme facilitates PDF generation since individual method calls do not need to be examined for failure; it is generally sufficient to wait until after Output() is called. For the same reason, if an error occurs in the calling application during PDF generation, it may be desirable for the application to transfer the error to the Fpdf instance by calling the SetError() method or the SetErrorf() method. At any time during the life cycle of the Fpdf instance, the error state can be determined with a call to Ok() or Err(). The error itself can be retrieved with a call to Error().

Conversion Notes

This package is a relatively straightforward translation from the original FPDF library written in PHP (despite the caveat in the introduction to Effective Go). The API names have been retained even though the Go idiom would suggest otherwise (for example, pdf.GetX() is used rather than simply pdf.X()). The similarity of the two libraries makes the original FPDF website a good source of information. It includes a forum and FAQ.

However, some internal changes have been made. Page content is built up using buffers (of type bytes.Buffer) rather than repeated string concatenation. Errors are handled as explained above rather than panicking. Output is generated through an interface of type io.Writer or io.WriteCloser. A number of the original PHP methods behave differently based on the type of the arguments that are passed to them; in these cases additional methods have been exported to provide similar functionality. Font definition files are produced in JSON rather than PHP.

Tutorials

A side effect of running "go test" is the production of the tutorial PDFs. These can be found in the gofpdf/pdf directory after the tests complete.

Please note that these tutorials run in the context of a test. In order run an example as a standalone application, you'll need to examine fpdf_test.go for some helper routines, for example docWriter and strDelimit. In particular, docWriter is used as an argument to OutputAndClose in order to reduce the boilerplate in each example. In practice, you may be better served by calling OutputFileAndClose().

Nonstandard Fonts

Nothing special is required to use the standard PDF fonts (courier, helvetica, times, zapfdingbats) in your documents other than calling SetFont().

In order to use a different TrueType or Type1 font, you will need to generate a font definition file and, if the font will be embedded into PDFs, a compressed version of the font file. This is done by calling the MakeFont function or using the included makefont command line utility. To create the utility, cd into the makefont subdirectory and run "go build". This will produce a standalone executable named makefont. Select the appropriate encoding file from the font subdirectory and run the command as in the following example.

./makefont --embed --enc=../font/cp1252.map --dst=../font ../font/calligra.ttf

In your PDF generation code, call AddFont() to load the font and, as with the standard fonts, SetFont() to begin using it. See tutorial 7 for an example. Good sources of free, open-source fonts include http://www.google.com/fonts/ and http://dejavu-fonts.org/.

Roadmap

• Handle UTF-8 source text natively. Until then, automatic translation of UTF-8 runes to code page bytes is provided.

• Improve test coverage as reported by the coverage tool.

Index

Examples

Constants

View Source
const (
	CnProtectPrint      = 4
	CnProtectModify     = 8
	CnProtectCopy       = 16
	CnProtectAnnotForms = 32
)

Advisory bitflag constants that control document activities

View Source
const (
	// FontSize is default font size
	FontSize = 4.0
)

Variables

This section is empty.

Functions

func MakeFont

func MakeFont(fontFileStr, encodingFileStr, dstDirStr string, msgWriter io.Writer, embed bool) (err error)

MakeFont generates a font definition file in JSON format. A definition file of this type is required to use non-core fonts in the PDF documents that gofpdf generates. See the makefont utility in the gofpdf package for a command line interface to this function.

fontFileStr is the name of the TrueType (or OpenType based on TrueType) or Type1 file from which to generate a definition file.

encodingFileStr is the name of the encoding file that corresponds to the font.

dstDirStr is the name of the directory in which to save the definition file and, if embed is true, the compressed font file.

msgWriter is the writer that is called to display messages throughout the process. Use nil to turn off messages.

embed is true if the font is to be embedded in the PDF files.

func UnicodeTranslator

func UnicodeTranslator(r io.Reader) (f func(string) string, err error)

UnicodeTranslator returns a function that can be used to translate, where possible, utf-8 strings to a form that is compatible with the specified code page. The returned function accepts a string and returns a string.

r is a reader that should read a buffer made up of content lines that pertain to the code page of interest. Each line is made up of three whitespace separated fields. The first begins with "!" and is followed by two hexadecimal digits that identify the glyph position in the code page of interest. The second field begins with "U+" and is followed by the unicode code point value. The third is the glyph name. A number of these code page map files are packaged with the gfpdf library in the font directory.

An error occurs only if a line is read that does not conform to the expected format. In this case, the returned function is valid but does not perform any rune translation.

func UnicodeTranslatorFromFile

func UnicodeTranslatorFromFile(fileStr string) (f func(string) string, err error)

UnicodeTranslatorFromFile returns a function that can be used to translate, where possible, utf-8 strings to a form that is compatible with the specified code page. See UnicodeTranslator for more details.

fileStr identifies a font descriptor file that maps glyph positions to names.

If an error occurs reading the file, the returned function is valid but does not perform any rune translation.

Types

type Fpdf

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

Fpdf is the principal structure for creating a single PDF document

Example (Tutorial01)

Hello, world. Note that since only core fonts are used (in this case Arial, a synonym for Helvetica), an empty string can be specified for the font directory in the call to New().

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"path/filepath"
)

// Absolute path needed for gocov tool; relative OK for test
const cnGofpdfDir = "."

func main() {
	pdf := gofpdf.New("P", "mm", "A4", "")
	pdf.AddPage()
	pdf.SetFont("Arial", "B", 16)
	pdf.Cell(40, 10, "Hello World!")
	fileStr := filepath.Join(cnGofpdfDir, "pdf/tutorial01.pdf")
	err := pdf.OutputFileAndClose(fileStr)
	if err == nil {
		fmt.Println("Successfully generated pdf/tutorial01.pdf")
	} else {
		fmt.Println(err)
	}
}
Output:

Successfully generated pdf/tutorial01.pdf
Example (Tutorial02)

Header, footer and page-breaking

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"os"
	"path/filepath"
)

// Absolute path needed for gocov tool; relative OK for test
const (
	cnGofpdfDir = "."

	cnImgDir = cnGofpdfDir + "/image"
)

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func imageFile(fileStr string) string {
	return filepath.Join(cnImgDir, fileStr)
}

func main() {
	pdf := gofpdf.New("P", "mm", "A4", "")
	pdf.SetHeaderFunc(func() {
		pdf.Image(imageFile("logo.png"), 10, 6, 30, 0, false, "", 0, "")
		pdf.SetY(5)
		pdf.SetFont("Arial", "B", 15)
		pdf.Cell(80, 0, "")
		pdf.CellFormat(30, 10, "Title", "1", 0, "C", false, 0, "")
		pdf.Ln(20)
	})
	pdf.SetFooterFunc(func() {
		pdf.SetY(-15)
		pdf.SetFont("Arial", "I", 8)
		pdf.CellFormat(0, 10, fmt.Sprintf("Page %d/{nb}", pdf.PageNo()), "", 0, "C", false, 0, "")
	})
	pdf.AliasNbPages("")
	pdf.AddPage()
	pdf.SetFont("Times", "", 12)
	for j := 1; j <= 40; j++ {
		pdf.CellFormat(0, 10, fmt.Sprintf("Printing line number %d", j), "", 1, "", false, 0, "")
	}
	pdf.OutputAndClose(docWriter(pdf, 2))
}
Output:

Successfully generated pdf/tutorial02.pdf
Example (Tutorial03)

Word-wrapping, line justification and page-breaking

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"io/ioutil"
	"os"
	"path/filepath"
)

// Absolute path needed for gocov tool; relative OK for test
const (
	cnGofpdfDir = "."

	cnTextDir = cnGofpdfDir + "/text"
)

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func textFile(fileStr string) string {
	return filepath.Join(cnTextDir, fileStr)
}

func main() {
	pdf := gofpdf.New("P", "mm", "A4", "")
	titleStr := "20000 Leagues Under the Seas"
	pdf.SetTitle(titleStr, false)
	pdf.SetAuthor("Jules Verne", false)
	pdf.SetHeaderFunc(func() {
		// Arial bold 15
		pdf.SetFont("Arial", "B", 15)
		// Calculate width of title and position
		wd := pdf.GetStringWidth(titleStr) + 6
		pdf.SetX((210 - wd) / 2)
		// Colors of frame, background and text
		pdf.SetDrawColor(0, 80, 180)
		pdf.SetFillColor(230, 230, 0)
		pdf.SetTextColor(220, 50, 50)
		// Thickness of frame (1 mm)
		pdf.SetLineWidth(1)
		// Title
		pdf.CellFormat(wd, 9, titleStr, "1", 1, "C", true, 0, "")
		// Line break
		pdf.Ln(10)
	})
	pdf.SetFooterFunc(func() {
		// Position at 1.5 cm from bottom
		pdf.SetY(-15)
		// Arial italic 8
		pdf.SetFont("Arial", "I", 8)
		// Text color in gray
		pdf.SetTextColor(128, 128, 128)
		// Page number
		pdf.CellFormat(0, 10, fmt.Sprintf("Page %d", pdf.PageNo()), "", 0, "C", false, 0, "")
	})
	chapterTitle := func(chapNum int, titleStr string) {
		// 	// Arial 12
		pdf.SetFont("Arial", "", 12)
		// Background color
		pdf.SetFillColor(200, 220, 255)
		// Title
		pdf.CellFormat(0, 6, fmt.Sprintf("Chapter %d : %s", chapNum, titleStr), "", 1, "L", true, 0, "")
		// Line break
		pdf.Ln(4)
	}
	chapterBody := func(fileStr string) {
		// Read text file
		txtStr, err := ioutil.ReadFile(fileStr)
		if err != nil {
			pdf.SetError(err)
		}
		// Times 12
		pdf.SetFont("Times", "", 12)
		// Output justified text
		pdf.MultiCell(0, 5, string(txtStr), "", "", false)
		// Line break
		pdf.Ln(-1)
		// Mention in italics
		pdf.SetFont("", "I", 0)
		pdf.Cell(0, 5, "(end of excerpt)")
	}
	printChapter := func(chapNum int, titleStr, fileStr string) {
		pdf.AddPage()
		chapterTitle(chapNum, titleStr)
		chapterBody(fileStr)
	}
	printChapter(1, "A RUNAWAY REEF", textFile("20k_c1.txt"))
	printChapter(2, "THE PROS AND CONS", textFile("20k_c2.txt"))
	pdf.OutputAndClose(docWriter(pdf, 3))
}
Output:

Successfully generated pdf/tutorial03.pdf
Example (Tutorial04)

Multiple column layout

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"io/ioutil"
	"os"
	"path/filepath"
)

// Absolute path needed for gocov tool; relative OK for test
const (
	cnGofpdfDir = "."

	cnTextDir = cnGofpdfDir + "/text"
)

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func textFile(fileStr string) string {
	return filepath.Join(cnTextDir, fileStr)
}

func main() {
	var y0 float64
	var crrntCol int
	pdf := gofpdf.New("P", "mm", "A4", "")
	pdf.SetDisplayMode("fullpage", "TwoColumnLeft")
	titleStr := "20000 Leagues Under the Seas"
	pdf.SetTitle(titleStr, false)
	pdf.SetAuthor("Jules Verne", false)
	setCol := func(col int) {
		// Set position at a given column
		crrntCol = col
		x := 10.0 + float64(col)*65.0
		pdf.SetLeftMargin(x)
		pdf.SetX(x)
	}
	chapterTitle := func(chapNum int, titleStr string) {
		// Arial 12
		pdf.SetFont("Arial", "", 12)
		// Background color
		pdf.SetFillColor(200, 220, 255)
		// Title
		pdf.CellFormat(0, 6, fmt.Sprintf("Chapter %d : %s", chapNum, titleStr), "", 1, "L", true, 0, "")
		// Line break
		pdf.Ln(4)
		y0 = pdf.GetY()
	}
	chapterBody := func(fileStr string) {
		// Read text file
		txtStr, err := ioutil.ReadFile(fileStr)
		if err != nil {
			pdf.SetError(err)
		}
		// Font
		pdf.SetFont("Times", "", 12)
		// Output text in a 6 cm width column
		pdf.MultiCell(60, 5, string(txtStr), "", "", false)
		pdf.Ln(-1)
		// Mention
		pdf.SetFont("", "I", 0)
		pdf.Cell(0, 5, "(end of excerpt)")
		// Go back to first column
		setCol(0)
	}
	printChapter := func(num int, titleStr, fileStr string) {
		// Add chapter
		pdf.AddPage()
		chapterTitle(num, titleStr)
		chapterBody(fileStr)
	}
	pdf.SetAcceptPageBreakFunc(func() bool {
		// Method accepting or not automatic page break
		if crrntCol < 2 {
			// Go to next column
			setCol(crrntCol + 1)
			// Set ordinate to top
			pdf.SetY(y0)
			// Keep on page
			return false
		}
		// Go back to first column
		setCol(0)
		// Page break
		return true
	})
	pdf.SetHeaderFunc(func() {
		// Arial bold 15
		pdf.SetFont("Arial", "B", 15)
		// Calculate width of title and position
		wd := pdf.GetStringWidth(titleStr) + 6
		pdf.SetX((210 - wd) / 2)
		// Colors of frame, background and text
		pdf.SetDrawColor(0, 80, 180)
		pdf.SetFillColor(230, 230, 0)
		pdf.SetTextColor(220, 50, 50)
		// Thickness of frame (1 mm)
		pdf.SetLineWidth(1)
		// Title
		pdf.CellFormat(wd, 9, titleStr, "1", 1, "C", true, 0, "")
		// Line break
		pdf.Ln(10)
		// Save ordinate
		y0 = pdf.GetY()
	})
	pdf.SetFooterFunc(func() {
		// Position at 1.5 cm from bottom
		pdf.SetY(-15)
		// Arial italic 8
		pdf.SetFont("Arial", "I", 8)
		// Text color in gray
		pdf.SetTextColor(128, 128, 128)
		// Page number
		pdf.CellFormat(0, 10, fmt.Sprintf("Page %d", pdf.PageNo()), "", 0, "C", false, 0, "")
	})
	printChapter(1, "A RUNAWAY REEF", textFile("20k_c1.txt"))
	printChapter(2, "THE PROS AND CONS", textFile("20k_c2.txt"))
	pdf.OutputAndClose(docWriter(pdf, 4))
}
Output:

Successfully generated pdf/tutorial04.pdf
Example (Tutorial05)

Various table styles

package main

import (
	"bufio"
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"os"
	"path/filepath"
	"strings"
)

// Absolute path needed for gocov tool; relative OK for test
const (
	cnGofpdfDir = "."

	cnTextDir = cnGofpdfDir + "/text"
)

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func textFile(fileStr string) string {
	return filepath.Join(cnTextDir, fileStr)
}

// Convert 'ABCDEFG' to, for example, 'A,BCD,EFG'
func strDelimit(str string, sepstr string, sepcount int) string {
	pos := len(str) - sepcount
	for pos > 0 {
		str = str[:pos] + sepstr + str[pos:]
		pos = pos - sepcount
	}
	return str
}

func main() {
	pdf := gofpdf.New("P", "mm", "A4", "")
	type countryType struct {
		nameStr, capitalStr, areaStr, popStr string
	}
	countryList := make([]countryType, 0, 8)
	header := []string{"Country", "Capital", "Area (sq km)", "Pop. (thousands)"}
	loadData := func(fileStr string) {
		fl, err := os.Open(fileStr)
		if err == nil {
			scanner := bufio.NewScanner(fl)
			var c countryType
			for scanner.Scan() {
				// Austria;Vienna;83859;8075
				lineStr := scanner.Text()
				list := strings.Split(lineStr, ";")
				if len(list) == 4 {
					c.nameStr = list[0]
					c.capitalStr = list[1]
					c.areaStr = list[2]
					c.popStr = list[3]
					countryList = append(countryList, c)
				} else {
					err = fmt.Errorf("error tokenizing %s", lineStr)
				}
			}
			fl.Close()
			if len(countryList) == 0 {
				err = fmt.Errorf("error loading data from %s", fileStr)
			}
		}
		if err != nil {
			pdf.SetError(err)
		}
	}
	// Simple table
	basicTable := func() {
		for _, str := range header {
			pdf.CellFormat(40, 7, str, "1", 0, "", false, 0, "")
		}
		pdf.Ln(-1)
		for _, c := range countryList {
			pdf.CellFormat(40, 6, c.nameStr, "1", 0, "", false, 0, "")
			pdf.CellFormat(40, 6, c.capitalStr, "1", 0, "", false, 0, "")
			pdf.CellFormat(40, 6, c.areaStr, "1", 0, "", false, 0, "")
			pdf.CellFormat(40, 6, c.popStr, "1", 0, "", false, 0, "")
			pdf.Ln(-1)
		}
	}
	// Better table
	improvedTable := func() {
		// Column widths
		w := []float64{40.0, 35.0, 40.0, 45.0}
		wSum := 0.0
		for _, v := range w {
			wSum += v
		}
		// 	Header
		for j, str := range header {
			pdf.CellFormat(w[j], 7, str, "1", 0, "C", false, 0, "")
		}
		pdf.Ln(-1)
		// Data
		for _, c := range countryList {
			pdf.CellFormat(w[0], 6, c.nameStr, "LR", 0, "", false, 0, "")
			pdf.CellFormat(w[1], 6, c.capitalStr, "LR", 0, "", false, 0, "")
			pdf.CellFormat(w[2], 6, strDelimit(c.areaStr, ",", 3), "LR", 0, "R", false, 0, "")
			pdf.CellFormat(w[3], 6, strDelimit(c.popStr, ",", 3), "LR", 0, "R", false, 0, "")
			pdf.Ln(-1)
		}
		pdf.CellFormat(wSum, 0, "", "T", 0, "", false, 0, "")
	}
	// Colored table
	fancyTable := func() {
		// Colors, line width and bold font
		pdf.SetFillColor(255, 0, 0)
		pdf.SetTextColor(255, 255, 255)
		pdf.SetDrawColor(128, 0, 0)
		pdf.SetLineWidth(.3)
		pdf.SetFont("", "B", 0)
		// 	Header
		w := []float64{40, 35, 40, 45}
		wSum := 0.0
		for _, v := range w {
			wSum += v
		}
		for j, str := range header {
			pdf.CellFormat(w[j], 7, str, "1", 0, "C", true, 0, "")
		}
		pdf.Ln(-1)
		// Color and font restoration
		pdf.SetFillColor(224, 235, 255)
		pdf.SetTextColor(0, 0, 0)
		pdf.SetFont("", "", 0)
		// 	Data
		fill := false
		for _, c := range countryList {
			pdf.CellFormat(w[0], 6, c.nameStr, "LR", 0, "", fill, 0, "")
			pdf.CellFormat(w[1], 6, c.capitalStr, "LR", 0, "", fill, 0, "")
			pdf.CellFormat(w[2], 6, strDelimit(c.areaStr, ",", 3), "LR", 0, "R", fill, 0, "")
			pdf.CellFormat(w[3], 6, strDelimit(c.popStr, ",", 3), "LR", 0, "R", fill, 0, "")
			pdf.Ln(-1)
			fill = !fill
		}
		pdf.CellFormat(wSum, 0, "", "T", 0, "", false, 0, "")
	}
	loadData(textFile("countries.txt"))
	pdf.SetFont("Arial", "", 14)
	pdf.AddPage()
	basicTable()
	pdf.AddPage()
	improvedTable()
	pdf.AddPage()
	fancyTable()
	pdf.OutputAndClose(docWriter(pdf, 5))
}
Output:

Successfully generated pdf/tutorial05.pdf
Example (Tutorial06)

This example demonstrates internal and external links with and without basic HTML.

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"os"
	"path/filepath"
)

// Absolute path needed for gocov tool; relative OK for test
const (
	cnGofpdfDir = "."

	cnImgDir = cnGofpdfDir + "/image"
)

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func imageFile(fileStr string) string {
	return filepath.Join(cnImgDir, fileStr)
}

func main() {
	pdf := gofpdf.New("P", "mm", "A4", "")
	// First page: manual local link
	pdf.AddPage()
	pdf.SetFont("Helvetica", "", 20)
	_, lineHt := pdf.GetFontSize()
	pdf.Write(lineHt, "To find out what's new in this tutorial, click ")
	pdf.SetFont("", "U", 0)
	link := pdf.AddLink()
	pdf.WriteLinkID(lineHt, "here", link)
	pdf.SetFont("", "", 0)
	// Second page: image link and basic HTML with link
	pdf.AddPage()
	pdf.SetLink(link, 0, -1)
	pdf.Image(imageFile("logo.png"), 10, 12, 30, 0, false, "", 0, "http://www.fpdf.org")
	pdf.SetLeftMargin(45)
	pdf.SetFontSize(14)
	_, lineHt = pdf.GetFontSize()
	htmlStr := `You can now easily print text mixing different styles: <b>bold</b>, ` +
		`<i>italic</i>, <u>underlined</u>, or <b><i><u>all at once</u></i></b>!<br><br>` +
		`You can also insert links on text, such as ` +
		`<a href="http://www.fpdf.org">www.fpdf.org</a>, or on an image: click on the logo.`
	html := pdf.HTMLBasicNew()
	html.Write(lineHt, htmlStr)
	pdf.OutputAndClose(docWriter(pdf, 6))
}
Output:

Successfully generated pdf/tutorial06.pdf
Example (Tutorial07)

Non-standard font

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"os"
)

// Absolute path needed for gocov tool; relative OK for test
const (
	cnGofpdfDir = "."
	cnFontDir   = cnGofpdfDir + "/font"
)

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func main() {
	pdf := gofpdf.New("P", "mm", "A4", cnFontDir)
	pdf.AddFont("Calligrapher", "", "calligra.json")
	pdf.AddPage()
	pdf.SetFont("Calligrapher", "", 35)
	pdf.Cell(0, 10, "Enjoy new fonts with FPDF!")
	pdf.OutputAndClose(docWriter(pdf, 7))
}
Output:

Successfully generated pdf/tutorial07.pdf
Example (Tutorial08)

Various image types

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"os"
	"path/filepath"
)

// Absolute path needed for gocov tool; relative OK for test
const (
	cnGofpdfDir = "."

	cnImgDir = cnGofpdfDir + "/image"
)

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func imageFile(fileStr string) string {
	return filepath.Join(cnImgDir, fileStr)
}

func main() {
	pdf := gofpdf.New("P", "mm", "A4", "")
	pdf.AddPage()
	pdf.SetFont("Arial", "", 11)
	pdf.Image(imageFile("logo.png"), 10, 10, 30, 0, false, "", 0, "")
	pdf.Text(50, 20, "logo.png")
	pdf.Image(imageFile("logo.gif"), 10, 40, 30, 0, false, "", 0, "")
	pdf.Text(50, 50, "logo.gif")
	pdf.Image(imageFile("logo-gray.png"), 10, 70, 30, 0, false, "", 0, "")
	pdf.Text(50, 80, "logo-gray.png")
	pdf.Image(imageFile("logo-rgb.png"), 10, 100, 30, 0, false, "", 0, "")
	pdf.Text(50, 110, "logo-rgb.png")
	pdf.Image(imageFile("logo.jpg"), 10, 130, 30, 0, false, "", 0, "")
	pdf.Text(50, 140, "logo.jpg")
	pdf.OutputAndClose(docWriter(pdf, 8))
}
Output:

Successfully generated pdf/tutorial08.pdf
Example (Tutorial09)

Landscape mode with logos

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"os"
	"path/filepath"
)

// Absolute path needed for gocov tool; relative OK for test
const (
	cnGofpdfDir = "."

	cnImgDir = cnGofpdfDir + "/image"
)

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func imageFile(fileStr string) string {
	return filepath.Join(cnImgDir, fileStr)
}

func lorem() string {
	return "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod " +
		"tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis " +
		"nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis " +
		"aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat " +
		"nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui " +
		"officia deserunt mollit anim id est laborum."
}

func main() {
	var y0 float64
	var crrntCol int
	loremStr := lorem()
	pdf := gofpdf.New("L", "mm", "A4", "")
	const (
		pageWd = 297.0 // A4 210.0 x 297.0
		margin = 10.0
		gutter = 4
		colNum = 3
		colWd  = (pageWd - 2*margin - (colNum-1)*gutter) / colNum
	)
	setCol := func(col int) {
		crrntCol = col
		x := margin + float64(col)*(colWd+gutter)
		pdf.SetLeftMargin(x)
		pdf.SetX(x)
	}
	pdf.SetHeaderFunc(func() {
		titleStr := "gofpdf"
		pdf.SetFont("Helvetica", "B", 48)
		wd := pdf.GetStringWidth(titleStr) + 6
		pdf.SetX((pageWd - wd) / 2)
		pdf.SetTextColor(128, 128, 160)
		pdf.Write(12, titleStr[:2])
		pdf.SetTextColor(128, 128, 128)
		pdf.Write(12, titleStr[2:])
		pdf.Ln(20)
		y0 = pdf.GetY()
	})
	pdf.SetAcceptPageBreakFunc(func() bool {
		if crrntCol < colNum-1 {
			setCol(crrntCol + 1)
			pdf.SetY(y0)
			// Start new column, not new page
			return false
		}
		setCol(0)
		return true
	})
	pdf.AddPage()
	pdf.SetFont("Times", "", 12)
	for j := 0; j < 20; j++ {
		if j == 1 {
			pdf.Image(imageFile("fpdf.png"), -1, 0, colWd, 0, true, "", 0, "")
		} else if j == 5 {
			pdf.Image(imageFile("golang-gopher.png"), -1, 0, colWd, 0, true, "", 0, "")
		}
		pdf.MultiCell(colWd, 5, loremStr, "", "", false)
		pdf.Ln(-1)
	}
	pdf.OutputAndClose(docWriter(pdf, 9))
}
Output:

Successfully generated pdf/tutorial09.pdf
Example (Tutorial10)

Test the corner cases as reported by the gocov tool

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"os"
	"path/filepath"
)

// Absolute path needed for gocov tool; relative OK for test
const (
	cnGofpdfDir = "."
	cnFontDir   = cnGofpdfDir + "/font"
)

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func fontFile(fileStr string) string {
	return filepath.Join(cnFontDir, fileStr)
}

func main() {
	gofpdf.MakeFont(fontFile("calligra.ttf"), fontFile("cp1252.map"), cnFontDir, nil, true)
	pdf := gofpdf.New("", "", "", "")
	pdf.SetFontLocation(cnFontDir)
	pdf.SetTitle("世界", true)
	pdf.SetAuthor("世界", true)
	pdf.SetSubject("世界", true)
	pdf.SetCreator("世界", true)
	pdf.SetKeywords("世界", true)
	pdf.AddFont("Calligrapher", "", "calligra.json")
	pdf.AddPage()
	pdf.SetFont("Calligrapher", "", 16)
	pdf.Writef(5, "\x95 %s \x95", pdf)
	pdf.OutputAndClose(docWriter(pdf, 10))
}
Output:

Successfully generated pdf/tutorial10.pdf
Example (Tutorial11)

Geometric figures

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"os"
)

// Absolute path needed for gocov tool; relative OK for test
const cnGofpdfDir = "."

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func main() {
	const (
		thin  = 0.2
		thick = 3.0
	)
	pdf := gofpdf.New("", "", "", "")
	pdf.SetFont("Helvetica", "", 12)
	pdf.SetFillColor(200, 200, 220)
	pdf.AddPage()

	y := 15.0
	pdf.Text(10, y, "Circles")
	pdf.SetFillColor(200, 200, 220)
	pdf.SetLineWidth(thin)
	pdf.Circle(20, y+15, 10, "D")
	pdf.Circle(45, y+15, 10, "F")
	pdf.Circle(70, y+15, 10, "FD")
	pdf.SetLineWidth(thick)
	pdf.Circle(95, y+15, 10, "FD")
	pdf.SetLineWidth(thin)

	y += 40.0
	pdf.Text(10, y, "Ellipses")
	pdf.SetFillColor(220, 200, 200)
	pdf.Ellipse(30, y+15, 20, 10, 0, "D")
	pdf.Ellipse(75, y+15, 20, 10, 0, "F")
	pdf.Ellipse(120, y+15, 20, 10, 0, "FD")
	pdf.SetLineWidth(thick)
	pdf.Ellipse(165, y+15, 20, 10, 0, "FD")
	pdf.SetLineWidth(thin)

	y += 40.0
	pdf.Text(10, y, "Curves (quadratic)")
	pdf.SetFillColor(220, 220, 200)
	pdf.Curve(10, y+30, 15, y-20, 40, y+30, "D")
	pdf.Curve(45, y+30, 50, y-20, 75, y+30, "F")
	pdf.Curve(80, y+30, 85, y-20, 110, y+30, "FD")
	pdf.SetLineWidth(thick)
	pdf.Curve(115, y+30, 120, y-20, 145, y+30, "FD")
	pdf.SetLineCapStyle("round")
	pdf.Curve(150, y+30, 155, y-20, 180, y+30, "FD")
	pdf.SetLineWidth(thin)
	pdf.SetLineCapStyle("butt")

	y += 40.0
	pdf.Text(10, y, "Curves (cubic)")
	pdf.SetFillColor(220, 200, 220)
	pdf.CurveBezierCubic(10, y+30, 15, y-20, 10, y+30, 40, y+30, "D")
	pdf.CurveBezierCubic(45, y+30, 50, y-20, 45, y+30, 75, y+30, "F")
	pdf.CurveBezierCubic(80, y+30, 85, y-20, 80, y+30, 110, y+30, "FD")
	pdf.SetLineWidth(thick)
	pdf.CurveBezierCubic(115, y+30, 120, y-20, 115, y+30, 145, y+30, "FD")
	pdf.SetLineCapStyle("round")
	pdf.CurveBezierCubic(150, y+30, 155, y-20, 150, y+30, 180, y+30, "FD")
	pdf.SetLineWidth(thin)
	pdf.SetLineCapStyle("butt")

	y += 40.0
	pdf.Text(10, y, "Arcs")
	pdf.SetFillColor(200, 220, 220)
	pdf.SetLineWidth(thick)
	pdf.Arc(45, y+35, 20, 10, 0, 0, 180, "FD")
	pdf.SetLineWidth(thin)
	pdf.Arc(45, y+35, 25, 15, 0, 90, 270, "D")
	pdf.SetLineWidth(thick)
	pdf.Arc(45, y+35, 30, 20, 0, 0, 360, "D")
	pdf.SetLineCapStyle("round")
	pdf.Arc(135, y+35, 20, 10, 135, 0, 180, "FD")
	pdf.SetLineWidth(thin)
	pdf.Arc(135, y+35, 25, 15, 135, 90, 270, "D")
	pdf.SetLineWidth(thick)
	pdf.Arc(135, y+35, 30, 20, 135, 0, 360, "D")
	pdf.SetLineWidth(thin)
	pdf.SetLineCapStyle("butt")

	pdf.OutputAndClose(docWriter(pdf, 11))
}
Output:

Successfully generated pdf/tutorial11.pdf
Example (Tutorial12)

Transparency

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"os"
	"path/filepath"
)

// Absolute path needed for gocov tool; relative OK for test
const (
	cnGofpdfDir = "."

	cnImgDir = cnGofpdfDir + "/image"
)

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func imageFile(fileStr string) string {
	return filepath.Join(cnImgDir, fileStr)
}

func main() {
	const (
		gapX  = 10.0
		gapY  = 9.0
		rectW = 40.0
		rectH = 58.0
		pageW = 210
		pageH = 297
	)
	modeList := []string{"Normal", "Multiply", "Screen", "Overlay",
		"Darken", "Lighten", "ColorDodge", "ColorBurn", "HardLight", "SoftLight",
		"Difference", "Exclusion", "Hue", "Saturation", "Color", "Luminosity"}
	pdf := gofpdf.New("", "", "", "")
	pdf.SetLineWidth(2)
	pdf.SetAutoPageBreak(false, 0)
	pdf.AddPage()
	pdf.SetFont("Helvetica", "", 18)
	pdf.SetXY(0, gapY)
	pdf.SetTextColor(0, 0, 0)
	pdf.CellFormat(pageW, gapY, "Alpha Blending Modes", "", 0, "C", false, 0, "")
	j := 0
	y := 3 * gapY
	for col := 0; col < 4; col++ {
		x := gapX
		for row := 0; row < 4; row++ {
			pdf.Rect(x, y, rectW, rectH, "D")
			pdf.SetFont("Helvetica", "B", 12)
			pdf.SetFillColor(0, 0, 0)
			pdf.SetTextColor(250, 250, 230)
			pdf.SetXY(x, y+rectH-4)
			pdf.CellFormat(rectW, 5, modeList[j], "", 0, "C", true, 0, "")
			pdf.SetFont("Helvetica", "I", 150)
			pdf.SetTextColor(80, 80, 120)
			pdf.SetXY(x, y+2)
			pdf.CellFormat(rectW, rectH, "A", "", 0, "C", false, 0, "")
			pdf.SetAlpha(0.5, modeList[j])
			pdf.Image(imageFile("golang-gopher.png"), x-gapX, y, rectW+2*gapX, 0, false, "", 0, "")
			pdf.SetAlpha(1.0, "Normal")
			x += rectW + gapX
			j++
		}
		y += rectH + gapY
	}
	pdf.OutputAndClose(docWriter(pdf, 12))
}
Output:

Successfully generated pdf/tutorial12.pdf
Example (Tutorial13)

Gradients

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"os"
)

// Absolute path needed for gocov tool; relative OK for test
const cnGofpdfDir = "."

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func main() {
	pdf := gofpdf.New("", "", "", "")
	pdf.SetFont("Helvetica", "", 12)
	pdf.AddPage()
	pdf.LinearGradient(0, 0, 210, 100, 250, 250, 255, 220, 220, 225, 0, 0, 0, .5)
	pdf.LinearGradient(20, 25, 75, 75, 220, 220, 250, 80, 80, 220, 0, .2, 0, .8)
	pdf.Rect(20, 25, 75, 75, "D")
	pdf.LinearGradient(115, 25, 75, 75, 220, 220, 250, 80, 80, 220, 0, 0, 1, 1)
	pdf.Rect(115, 25, 75, 75, "D")
	pdf.RadialGradient(20, 120, 75, 75, 220, 220, 250, 80, 80, 220, 0.25, 0.75, 0.25, 0.75, 1)
	pdf.Rect(20, 120, 75, 75, "D")
	pdf.RadialGradient(115, 120, 75, 75, 220, 220, 250, 80, 80, 220, 0.25, 0.75, 0.75, 0.75, 0.75)
	pdf.Rect(115, 120, 75, 75, "D")
	pdf.OutputAndClose(docWriter(pdf, 13))
}
Output:

Successfully generated pdf/tutorial13.pdf
Example (Tutorial14)

Clipping examples

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"os"
	"path/filepath"
)

// Absolute path needed for gocov tool; relative OK for test
const (
	cnGofpdfDir = "."

	cnImgDir = cnGofpdfDir + "/image"
)

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func imageFile(fileStr string) string {
	return filepath.Join(cnImgDir, fileStr)
}

func lorem() string {
	return "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod " +
		"tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis " +
		"nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis " +
		"aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat " +
		"nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui " +
		"officia deserunt mollit anim id est laborum."
}

func main() {
	pdf := gofpdf.New("", "", "", "")
	y := 10.0
	pdf.AddPage()

	pdf.SetFont("Helvetica", "", 24)
	pdf.SetXY(0, y)
	pdf.ClipText(10, y+12, "Clipping examples", false)
	pdf.RadialGradient(10, y, 100, 20, 128, 128, 160, 32, 32, 48, 0.25, 0.5, 0.25, 0.5, 0.2)
	pdf.ClipEnd()

	y += 12
	pdf.SetFont("Helvetica", "B", 120)
	pdf.SetDrawColor(64, 80, 80)
	pdf.SetLineWidth(.5)
	pdf.ClipText(10, y+40, pdf.String(), true)
	pdf.RadialGradient(10, y, 200, 50, 220, 220, 250, 80, 80, 220, 0.25, 0.5, 0.25, 0.5, 1)
	pdf.ClipEnd()

	y += 55
	pdf.ClipRect(10, y, 105, 20, true)
	pdf.SetFillColor(255, 255, 255)
	pdf.Rect(10, y, 105, 20, "F")
	pdf.ClipCircle(40, y+10, 15, false)
	pdf.RadialGradient(25, y, 30, 30, 220, 250, 220, 40, 60, 40, 0.3, 0.85, 0.3, 0.85, 0.5)
	pdf.ClipEnd()
	pdf.ClipEllipse(80, y+10, 20, 15, false)
	pdf.RadialGradient(60, y, 40, 30, 250, 220, 220, 60, 40, 40, 0.3, 0.85, 0.3, 0.85, 0.5)
	pdf.ClipEnd()
	pdf.ClipEnd()

	y += 28
	pdf.ClipEllipse(26, y+10, 16, 10, true)
	pdf.Image(imageFile("logo.jpg"), 10, y, 32, 0, false, "JPG", 0, "")
	pdf.ClipEnd()

	pdf.ClipCircle(60, y+10, 10, true)
	pdf.RadialGradient(50, y, 20, 20, 220, 220, 250, 40, 40, 60, 0.3, 0.7, 0.3, 0.7, 0.5)
	pdf.ClipEnd()

	pdf.ClipPolygon([]gofpdf.PointType{{80, y + 20}, {90, y}, {100, y + 20}}, true)
	pdf.LinearGradient(80, y, 20, 20, 250, 220, 250, 60, 40, 60, 0.5, 1, 0.5, 0.5)
	pdf.ClipEnd()

	y += 30
	pdf.SetLineWidth(.1)
	pdf.SetDrawColor(180, 180, 180)
	pdf.ClipRoundedRect(10, y, 120, 20, 5, true)
	pdf.RadialGradient(10, y, 120, 20, 255, 255, 255, 240, 240, 220, 0.25, 0.75, 0.25, 0.75, 0.5)
	pdf.SetXY(5, y-5)
	pdf.SetFont("Times", "", 12)
	pdf.MultiCell(130, 5, lorem(), "", "", false)
	pdf.ClipEnd()

	pdf.OutputAndClose(docWriter(pdf, 14))
}
Output:

Successfully generated pdf/tutorial14.pdf
Example (Tutorial15)

Page size example

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"os"
)

// Absolute path needed for gocov tool; relative OK for test
const (
	cnGofpdfDir = "."
	cnFontDir   = cnGofpdfDir + "/font"
)

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func main() {
	pdf := gofpdf.NewCustom(&gofpdf.InitType{
		UnitStr:    "in",
		Size:       gofpdf.SizeType{Wd: 6, Ht: 6},
		FontDirStr: cnFontDir,
	})
	pdf.SetMargins(0.5, 1, 0.5)
	pdf.SetFont("Times", "", 14)
	pdf.AddPageFormat("L", gofpdf.SizeType{Wd: 3, Ht: 12})
	pdf.SetXY(0.5, 1.5)
	pdf.CellFormat(11, 0.2, "12 in x 3 in", "", 0, "C", false, 0, "")
	pdf.AddPage() // Default size established in NewCustom()
	pdf.SetXY(0.5, 3)
	pdf.CellFormat(5, 0.2, "6 in x 6 in", "", 0, "C", false, 0, "")
	pdf.AddPageFormat("P", gofpdf.SizeType{Wd: 3, Ht: 12})
	pdf.SetXY(0.5, 6)
	pdf.CellFormat(2, 0.2, "3 in x 12 in", "", 0, "C", false, 0, "")
	for j := 0; j <= 3; j++ {
		wd, ht, u := pdf.PageSize(j)
		fmt.Printf("%d: %6.2f %s, %6.2f %s\n", j, wd, u, ht, u)
	}
	pdf.OutputAndClose(docWriter(pdf, 15))
}
Output:

0:   6.00 in,   6.00 in
1:  12.00 in,   3.00 in
2:   6.00 in,   6.00 in
3:   3.00 in,  12.00 in
Successfully generated pdf/tutorial15.pdf
Example (Tutorial16)

Bookmark test

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"os"
)

// Absolute path needed for gocov tool; relative OK for test
const cnGofpdfDir = "."

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func main() {
	pdf := gofpdf.New("P", "mm", "A4", "")
	pdf.AddPage()
	pdf.SetFont("Arial", "", 15)
	pdf.Bookmark("Page 1", 0, 0)
	pdf.Bookmark("Paragraph 1", 1, -1)
	pdf.Cell(0, 6, "Paragraph 1")
	pdf.Ln(50)
	pdf.Bookmark("Paragraph 2", 1, -1)
	pdf.Cell(0, 6, "Paragraph 2")
	pdf.AddPage()
	pdf.Bookmark("Page 2", 0, 0)
	pdf.Bookmark("Paragraph 3", 1, -1)
	pdf.Cell(0, 6, "Paragraph 3")
	pdf.OutputAndClose(docWriter(pdf, 16))
}
Output:

Successfully generated pdf/tutorial16.pdf
Example (Tutorial17)

Transformation test adapted from an example script by Moritz Wagner and Andreas Würmser.

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"os"
)

// Absolute path needed for gocov tool; relative OK for test
const cnGofpdfDir = "."

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func main() {
	const (
		light = 200
		dark  = 0
	)
	var refX, refY float64
	var refStr string
	pdf := gofpdf.New("P", "mm", "A4", "")
	pdf.AddPage()
	color := func(val int) {
		pdf.SetDrawColor(val, val, val)
		pdf.SetTextColor(val, val, val)
	}
	reference := func(str string, x, y float64, val int) {
		color(val)
		pdf.Rect(x, y, 40, 10, "D")
		pdf.Text(x, y-1, str)
	}
	refDraw := func(str string, x, y float64) {
		refStr = str
		refX = x
		refY = y
		reference(str, x, y, light)
	}
	refDupe := func() {
		reference(refStr, refX, refY, dark)
	}

	titleStr := "Transformations"
	titlePt := 36.0
	titleHt := pdf.PointConvert(titlePt)
	pdf.SetFont("Helvetica", "", titlePt)
	titleWd := pdf.GetStringWidth(titleStr)
	titleX := (210 - titleWd) / 2
	pdf.Text(titleX, 10+titleHt, titleStr)
	pdf.TransformBegin()
	pdf.TransformMirrorVertical(10 + titleHt + 0.5)
	pdf.ClipText(titleX, 10+titleHt, titleStr, false)
	// Remember that the transform will mirror the gradient box too
	pdf.LinearGradient(titleX, 10, titleWd, titleHt+4, 120, 120, 120, 255, 255, 255, 0, 0, 0, 0.6)
	pdf.ClipEnd()
	pdf.TransformEnd()

	pdf.SetFont("Helvetica", "", 12)

	// Scale by 150% centered by lower left corner of the rectangle
	refDraw("Scale", 50, 60)
	pdf.TransformBegin()
	pdf.TransformScaleXY(150, 50, 70)
	refDupe()
	pdf.TransformEnd()

	// Translate 7 to the right, 5 to the bottom
	refDraw("Translate", 125, 60)
	pdf.TransformBegin()
	pdf.TransformTranslate(7, 5)
	refDupe()
	pdf.TransformEnd()

	// Rotate 20 degrees counter-clockwise centered by the lower left corner of
	// the rectangle
	refDraw("Rotate", 50, 110)
	pdf.TransformBegin()
	pdf.TransformRotate(20, 50, 120)
	refDupe()
	pdf.TransformEnd()

	// Skew 30 degrees along the x-axis centered by the lower left corner of the
	// rectangle
	refDraw("Skew", 125, 110)
	pdf.TransformBegin()
	pdf.TransformSkewX(30, 125, 110)
	refDupe()
	pdf.TransformEnd()

	// Mirror horizontally with axis of reflection at left side of the rectangle
	refDraw("Mirror horizontal", 50, 160)
	pdf.TransformBegin()
	pdf.TransformMirrorHorizontal(50)
	refDupe()
	pdf.TransformEnd()

	// Mirror vertically with axis of reflection at bottom side of the rectangle
	refDraw("Mirror vertical", 125, 160)
	pdf.TransformBegin()
	pdf.TransformMirrorVertical(170)
	refDupe()
	pdf.TransformEnd()

	// Reflect against a point at the lower left point of rectangle
	refDraw("Mirror point", 50, 210)
	pdf.TransformBegin()
	pdf.TransformMirrorPoint(50, 220)
	refDupe()
	pdf.TransformEnd()

	// Mirror against a straight line described by a point and an angle
	angle := -20.0
	px := 120.0
	py := 220.0
	refDraw("Mirror line", 125, 210)
	pdf.TransformBegin()
	pdf.TransformRotate(angle, px, py)
	pdf.Line(px-1, py-1, px+1, py+1)
	pdf.Line(px-1, py+1, px+1, py-1)
	pdf.Line(px-5, py, px+60, py)
	pdf.TransformEnd()
	pdf.TransformBegin()
	pdf.TransformMirrorLine(angle, px, py)
	refDupe()
	pdf.TransformEnd()

	pdf.OutputAndClose(docWriter(pdf, 17))
}
Output:

Successfully generated pdf/tutorial17.pdf
Example (Tutorial18)

Example to demonstrate Lawrence Kesteloot's image registration code.

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"os"
	"path/filepath"
)

// Absolute path needed for gocov tool; relative OK for test
const (
	cnGofpdfDir = "."

	cnImgDir = cnGofpdfDir + "/image"
)

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func imageFile(fileStr string) string {
	return filepath.Join(cnImgDir, fileStr)
}

func main() {
	const (
		margin = 10
		wd     = 210
		ht     = 297
	)
	fileList := []string{
		"logo-gray.png",
		"logo.jpg",
		"logo.png",
		"logo-rgb.png",
		"logo-progressive.jpg",
	}
	var infoPtr *gofpdf.ImageInfoType
	var fileStr string
	var imgWd, imgHt, lf, tp float64
	pdf := gofpdf.New("P", "mm", "A4", "")
	pdf.AddPage()
	pdf.SetMargins(10, 10, 10)
	pdf.SetFont("Helvetica", "", 15)
	for j, str := range fileList {
		fileStr = imageFile(str)
		infoPtr = pdf.RegisterImage(fileStr, "")
		imgWd, imgHt = infoPtr.Extent()
		switch j {
		case 0:
			lf = margin
			tp = margin
		case 1:
			lf = wd - margin - imgWd
			tp = margin
		case 2:
			lf = (wd - imgWd) / 2.0
			tp = (ht - imgHt) / 2.0
		case 3:
			lf = margin
			tp = ht - imgHt - margin
		case 4:
			lf = wd - imgWd - margin
			tp = ht - imgHt - margin
		}
		pdf.Image(fileStr, lf, tp, imgWd, imgHt, false, "", 0, "")
	}
	pdf.OutputAndClose(docWriter(pdf, 18))
}
Output:

Successfully generated pdf/tutorial18.pdf
Example (Tutorial19)

Example to demonstrate Bruno Michel's line splitting function.

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"os"
)

// Absolute path needed for gocov tool; relative OK for test
const cnGofpdfDir = "."

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func lorem() string {
	return "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod " +
		"tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis " +
		"nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis " +
		"aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat " +
		"nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui " +
		"officia deserunt mollit anim id est laborum."
}

func main() {
	const (
		fontPtSize = 18.0
		wd         = 100.0
	)
	pdf := gofpdf.New("P", "mm", "A4", "") // A4 210.0 x 297.0
	pdf.SetFont("Times", "", fontPtSize)
	_, lineHt := pdf.GetFontSize()
	pdf.AddPage()
	pdf.SetMargins(10, 10, 10)
	lines := pdf.SplitLines([]byte(lorem()), wd)
	ht := float64(len(lines)) * lineHt
	y := (297.0 - ht) / 2.0
	pdf.SetDrawColor(128, 128, 128)
	pdf.SetFillColor(255, 255, 210)
	x := (210.0 - (wd + 40.0)) / 2.0
	pdf.Rect(x, y-20.0, wd+40.0, ht+40.0, "FD")
	pdf.SetY(y)
	for _, line := range lines {
		pdf.CellFormat(190.0, lineHt, string(line), "", 1, "C", false, 0, "")
	}
	pdf.OutputAndClose(docWriter(pdf, 19))
}
Output:

Successfully generated pdf/tutorial19.pdf
Example (Tutorial20)

This example demonstrates how to render a simple path-only SVG image of the type generated by the jSignature web control.

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"os"
	"path/filepath"
)

// Absolute path needed for gocov tool; relative OK for test
const (
	cnGofpdfDir = "."

	cnImgDir = cnGofpdfDir + "/image"
)

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func imageFile(fileStr string) string {
	return filepath.Join(cnImgDir, fileStr)
}

func main() {
	const (
		fontPtSize = 16.0
		wd         = 100.0
		sigFileStr = "signature.svg"
	)
	var (
		sig gofpdf.SVGBasicType
		err error
	)
	pdf := gofpdf.New("P", "mm", "A4", "") // A4 210.0 x 297.0
	pdf.SetFont("Times", "", fontPtSize)
	lineHt := pdf.PointConvert(fontPtSize)
	pdf.AddPage()
	pdf.SetMargins(10, 10, 10)
	htmlStr := `This example renders a simple ` +
		`<a href="http://www.w3.org/TR/SVG/">SVG</a> (scalable vector graphics) ` +
		`image that contains only basic path commands without any styling, ` +
		`color fill, reflection or endpoint closures. In particular, the ` +
		`type of vector graphic returned from a ` +
		`<a href="http://willowsystems.github.io/jSignature/#/demo/">jSignature</a> ` +
		`web control is supported and is used in this example.`
	html := pdf.HTMLBasicNew()
	html.Write(lineHt, htmlStr)
	sig, err = gofpdf.SVGBasicFileParse(imageFile(sigFileStr))
	if err == nil {
		scale := 100 / sig.Wd
		scaleY := 30 / sig.Ht
		if scale > scaleY {
			scale = scaleY
		}
		pdf.SetLineCapStyle("round")
		pdf.SetLineWidth(0.25)
		pdf.SetDrawColor(0, 0, 128)
		pdf.SetXY((210.0-scale*sig.Wd)/2.0, pdf.GetY()+10)
		pdf.SVGBasicWrite(&sig, scale)
	} else {
		pdf.SetError(err)
	}
	pdf.OutputAndClose(docWriter(pdf, 20))
}
Output:

Successfully generated pdf/tutorial20.pdf
Example (Tutorial21)

This example demonstrates Stefan Schroeder's code to control vertical alignment.

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"os"
)

// Absolute path needed for gocov tool; relative OK for test
const cnGofpdfDir = "."

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func main() {
	type recType struct {
		align, txt string
	}
	recList := []recType{
		recType{"TL", "top left"},
		recType{"TC", "top center"},
		recType{"TR", "top right"},
		recType{"LM", "middle left"},
		recType{"CM", "middle center"},
		recType{"RM", "middle right"},
		recType{"BL", "bottom left"},
		recType{"BC", "bottom center"},
		recType{"BR", "bottom right"},
	}
	pdf := gofpdf.New("P", "mm", "A4", "") // A4 210.0 x 297.0
	pdf.SetFont("Helvetica", "", 16)
	linkStr := ""
	for pageJ := 0; pageJ < 2; pageJ++ {
		pdf.AddPage()
		pdf.SetMargins(10, 10, 10)
		pdf.SetAutoPageBreak(false, 0)
		borderStr := "1"
		for _, rec := range recList {
			pdf.SetXY(20, 20)
			pdf.CellFormat(170, 257, rec.txt, borderStr, 0, rec.align, false, 0, linkStr)
			borderStr = ""
		}
		linkStr = "https://github.com/jung-kurt/gofpdf"
	}
	pdf.OutputAndClose(docWriter(pdf, 21))
}
Output:

Successfully generated pdf/tutorial21.pdf
Example (Tutorial22)

This example demonstrates the use of characters in the high range of the Windows-1252 code page (gofdpf default). See the following example (23) for a way to do this automatically.

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"os"
)

// Absolute path needed for gocov tool; relative OK for test
const cnGofpdfDir = "."

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func main() {
	pdf := gofpdf.New("P", "mm", "A4", "") // A4 210.0 x 297.0
	fontSize := 16.0
	pdf.SetFont("Helvetica", "", fontSize)
	ht := pdf.PointConvert(fontSize)
	write := func(str string) {
		pdf.CellFormat(190, ht, str, "", 1, "C", false, 0, "")
		pdf.Ln(ht)
	}
	pdf.AddPage()
	htmlStr := `Until gofpdf supports UTF-8 encoded source text, source text needs ` +
		`to be specified with all special characters escaped to match the code page ` +
		`layout of the currently selected font. By default, gofdpf uses code page 1252.` +
		` See <a href="http://en.wikipedia.org/wiki/Windows-1252">Wikipedia</a> for ` +
		`a table of this layout.`
	html := pdf.HTMLBasicNew()
	html.Write(ht, htmlStr)
	pdf.Ln(2 * ht)
	write("Voix ambigu\xeb d'un c\x9cur qui au z\xe9phyr pr\xe9f\xe8re les jattes de kiwi.")
	write("Falsches \xdcben von Xylophonmusik qu\xe4lt jeden gr\xf6\xdferen Zwerg.")
	write("Heiz\xf6lr\xfccksto\xdfabd\xe4mpfung")
	write("For\xe5rsj\xe6vnd\xf8gn / Efter\xe5rsj\xe6vnd\xf8gn")
	pdf.OutputAndClose(docWriter(pdf, 22))
}
Output:

Successfully generated pdf/tutorial22.pdf
Example (Tutorial23)

This example demonstrates the conversion of UTF-8 strings to an 8-bit font encoding.

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"os"
)

// Absolute path needed for gocov tool; relative OK for test
const (
	cnGofpdfDir = "."
	cnFontDir   = cnGofpdfDir + "/font"
)

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func main() {
	pdf := gofpdf.New("P", "mm", "A4", cnFontDir) // A4 210.0 x 297.0
	// See documentation for details on how to generate fonts
	pdf.AddFont("Helvetica-1251", "", "helvetica_1251.json")
	pdf.AddFont("Helvetica-1253", "", "helvetica_1253.json")
	fontSize := 16.0
	pdf.SetFont("Helvetica", "", fontSize)
	ht := pdf.PointConvert(fontSize)
	tr := pdf.UnicodeTranslatorFromDescriptor("") // "" defaults to "cp1252"
	write := func(str string) {
		pdf.CellFormat(190, ht, tr(str), "", 1, "C", false, 0, "")
		pdf.Ln(ht)
	}
	pdf.AddPage()
	str := `Gofpdf provides a translator that will convert any UTF-8 code point ` +
		`that is present in the specified code page.`
	pdf.MultiCell(190, ht, str, "", "L", false)
	pdf.Ln(2 * ht)
	write("Voix ambiguë d'un cœur qui au zéphyr préfère les jattes de kiwi.")
	write("Falsches Üben von Xylophonmusik quält jeden größeren Zwerg.")
	write("Heizölrückstoßabdämpfung")
	write("Forårsjævndøgn / Efterårsjævndøgn")

	pdf.SetFont("Helvetica-1251", "", fontSize) // Name matches one specified in AddFont()
	tr = pdf.UnicodeTranslatorFromDescriptor("cp1251")
	write("Съешь же ещё этих мягких французских булок, да выпей чаю.")

	pdf.SetFont("Helvetica-1253", "", fontSize)
	tr = pdf.UnicodeTranslatorFromDescriptor("cp1253")
	write("Θέλει αρετή και τόλμη η ελευθερία. (Ανδρέας Κάλβος)")

	pdf.OutputAndClose(docWriter(pdf, 23))
}
Output:

Successfully generated pdf/tutorial23.pdf
Example (Tutorial24)

This example demonstrates document protection.

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"os"
)

// Absolute path needed for gocov tool; relative OK for test
const cnGofpdfDir = "."

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func main() {
	pdf := gofpdf.New("P", "mm", "A4", "")
	pdf.SetProtection(gofpdf.CnProtectPrint, "123", "abc")
	pdf.AddPage()
	pdf.SetFont("Arial", "", 12)
	pdf.Write(10, "Password-protected.")
	pdf.OutputAndClose(docWriter(pdf, 24))
}
Output:

Successfully generated pdf/tutorial24.pdf
Example (Tutorial25)

This example displays equilateral polygons in a demonstration of the Polygon function.

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"math"
	"os"
)

// Absolute path needed for gocov tool; relative OK for test
const cnGofpdfDir = "."

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func main() {
	const rowCount = 5
	const colCount = 4
	const ptSize = 36
	var x, y, radius, gap, advance float64
	var rgVal int
	var pts []gofpdf.PointType
	vertices := func(count int) (res []gofpdf.PointType) {
		var pt gofpdf.PointType
		res = make([]gofpdf.PointType, 0, count)
		mlt := 2.0 * math.Pi / float64(count)
		for j := 0; j < count; j++ {
			pt.Y, pt.X = math.Sincos(float64(j) * mlt)
			res = append(res, gofpdf.PointType{X: x + radius*pt.X, Y: y + radius*pt.Y})
		}
		return
	}
	pdf := gofpdf.New("P", "mm", "A4", "") // A4 210.0 x 297.0
	pdf.AddPage()
	pdf.SetFont("Helvetica", "", ptSize)
	pdf.SetDrawColor(0, 80, 180)
	gap = 12.0
	pdf.SetY(gap)
	pdf.CellFormat(190.0, gap, "Equilateral polygons", "", 1, "C", false, 0, "")
	radius = (210.0 - float64(colCount+1)*gap) / (2.0 * float64(colCount))
	advance = gap + 2.0*radius
	y = 2*gap + pdf.PointConvert(ptSize) + radius
	rgVal = 230
	for row := 0; row < rowCount; row++ {
		pdf.SetFillColor(rgVal, rgVal, 0)
		rgVal -= 12
		x = gap + radius
		for col := 0; col < colCount; col++ {
			pts = vertices(row*colCount + col + 3)
			pdf.Polygon(pts, "FD")
			x += advance
		}
		y += advance
	}
	pdf.OutputAndClose(docWriter(pdf, 25))
}
Output:

Successfully generated pdf/tutorial25.pdf
Example (Tutorial26)

This example demonstrates document layers. The initial visibility of a layer is specified with the second parameter to AddLayer(). The layer list displayed by the document reader allows layer visibility to be controlled interactively.

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"os"
)

// Absolute path needed for gocov tool; relative OK for test
const cnGofpdfDir = "."

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func main() {

	pdf := gofpdf.New("P", "mm", "A4", "")
	pdf.AddPage()
	pdf.SetFont("Arial", "", 15)
	pdf.Write(8, "This line doesn't belong to any layer.\n")

	// Define layers
	l1 := pdf.AddLayer("Layer 1", true)
	l2 := pdf.AddLayer("Layer 2", true)

	// Open layer pane in PDF viewer
	pdf.OpenLayerPane()

	// First layer
	pdf.BeginLayer(l1)
	pdf.Write(8, "This line belongs to layer 1.\n")
	pdf.EndLayer()

	// Second layer
	pdf.BeginLayer(l2)
	pdf.Write(8, "This line belongs to layer 2.\n")
	pdf.EndLayer()

	// First layer again
	pdf.BeginLayer(l1)
	pdf.Write(8, "This line belongs to layer 1 again.\n")
	pdf.EndLayer()

	pdf.OutputAndClose(docWriter(pdf, 26))
}
Output:

Successfully generated pdf/tutorial26.pdf
Example (Tutorial27)

This example demonstrates the use of an image that is retrieved from a web server.

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"net/http"
	"os"
)

// Absolute path needed for gocov tool; relative OK for test
const cnGofpdfDir = "."

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func main() {

	const (
		margin   = 10
		wd       = 210
		ht       = 297
		fontSize = 15
		urlStr   = "https://github.com/jung-kurt/gofpdf/blob/master/image/gofpdf.png?raw=true"
		msgStr   = `Images from the web can be easily embedded when a PDF document is generated.`
	)

	var (
		rsp *http.Response
		err error
		tp  string
	)

	pdf := gofpdf.New("P", "mm", "A4", "")
	pdf.AddPage()
	pdf.SetFont("Helvetica", "", fontSize)
	ln := pdf.PointConvert(fontSize)
	pdf.MultiCell(wd-margin-margin, ln, msgStr, "", "L", false)
	rsp, err = http.Get(urlStr)
	if err == nil {
		tp = pdf.ImageTypeFromMime(rsp.Header["Content-Type"][0])
		infoPtr := pdf.RegisterImageReader(urlStr, tp, rsp.Body)
		if pdf.Ok() {
			imgWd, imgHt := infoPtr.Extent()
			pdf.Image(urlStr, (wd-imgWd)/2.0, pdf.GetY()+ln, imgWd, imgHt, false, tp, 0, "")
		}
	} else {
		pdf.SetError(err)
	}
	pdf.OutputAndClose(docWriter(pdf, 27))
}
Output:

Successfully generated pdf/tutorial27.pdf
Example (Tutorial28)

This example demonstrates the Beziergon function.

package main

import (
	"fmt"
	"github.com/jung-kurt/gofpdf"
	"os"
)

// Absolute path needed for gocov tool; relative OK for test
const cnGofpdfDir = "."

type pdfWriter struct {
	pdf *gofpdf.Fpdf
	fl  *os.File
	idx int
}

func (pw *pdfWriter) Write(p []byte) (n int, err error) {
	if pw.pdf.Ok() {
		return pw.fl.Write(p)
	}
	return
}

func (pw *pdfWriter) Close() (err error) {
	if pw.fl != nil {
		pw.fl.Close()
		pw.fl = nil
	}
	if pw.pdf.Ok() {
		fmt.Printf("Successfully generated pdf/tutorial%02d.pdf\n", pw.idx)
	} else {
		fmt.Printf("%s\n", pw.pdf.Error())
	}
	return
}

func docWriter(pdf *gofpdf.Fpdf, idx int) *pdfWriter {
	pw := new(pdfWriter)
	pw.pdf = pdf
	pw.idx = idx
	if pdf.Ok() {
		var err error
		fileStr := fmt.Sprintf("%s/pdf/tutorial%02d.pdf", cnGofpdfDir, idx)
		pw.fl, err = os.Create(fileStr)
		if err != nil {
			pdf.SetErrorf("Error opening output file %s", fileStr)
		}
	}
	return pw
}

func main() {

	const (
		margin      = 10
		wd          = 210
		unit        = (wd - 2*margin) / 6
		ht          = 297
		fontSize    = 15
		msgStr      = `Demonstration of Beziergon function`
		coefficient = 0.6
		delta       = coefficient * unit
		ln          = fontSize * 25.4 / 72
		offsetX     = (wd - 4*unit) / 2.0
		offsetY     = offsetX + 2*ln
	)

	srcList := []gofpdf.PointType{
		{X: 0, Y: 0},
		{X: 1, Y: 0},
		{X: 1, Y: 1},
		{X: 2, Y: 1},
		{X: 2, Y: 2},
		{X: 3, Y: 2},
		{X: 3, Y: 3},
		{X: 4, Y: 3},
		{X: 4, Y: 4},
		{X: 1, Y: 4},
		{X: 1, Y: 3},
		{X: 0, Y: 3},
	}

	ctrlList := []gofpdf.PointType{
		{X: 1, Y: -1},
		{X: 1, Y: 1},
		{X: 1, Y: 1},
		{X: 1, Y: 1},
		{X: 1, Y: 1},
		{X: 1, Y: 1},
		{X: 1, Y: 1},
		{X: 1, Y: 1},
		{X: -1, Y: 1},
		{X: -1, Y: -1},
		{X: -1, Y: -1},
		{X: -1, Y: -1},
	}

	pdf := gofpdf.New("P", "mm", "A4", "")
	pdf.AddPage()
	pdf.SetFont("Helvetica", "", fontSize)
	for j, src := range srcList {
		srcList[j].X = offsetX + src.X*unit
		srcList[j].Y = offsetY + src.Y*unit
	}
	for j, ctrl := range ctrlList {
		ctrlList[j].X = ctrl.X * delta
		ctrlList[j].Y = ctrl.Y * delta
	}
	jPrev := len(srcList) - 1
	srcPrev := srcList[jPrev]
	curveList := []gofpdf.PointType{srcPrev} // point [, control 0, control 1, point]*
	control := func(x, y float64) {
		curveList = append(curveList, gofpdf.PointType{X: x, Y: y})
	}
	for j, src := range srcList {
		ctrl := ctrlList[jPrev]
		control(srcPrev.X+ctrl.X, srcPrev.Y+ctrl.Y) // Control 0
		ctrl = ctrlList[j]
		control(src.X-ctrl.X, src.Y-ctrl.Y) // Control 1
		curveList = append(curveList, src)  // Destination
		jPrev = j
		srcPrev = src
	}
	pdf.MultiCell(wd-margin-margin, ln, msgStr, "", "C", false)
	pdf.SetDrawColor(224, 224, 224)
	pdf.Polygon(srcList, "D")
	pdf.SetDrawColor(64, 64, 128)
	pdf.SetLineWidth(pdf.GetLineWidth() * 3)
	pdf.Beziergon(curveList, "D")
	pdf.OutputAndClose(docWriter(pdf, 28))
}
Output:

Successfully generated pdf/tutorial28.pdf

func New

func New(orientationStr, unitStr, sizeStr, fontDirStr string) (f *Fpdf)

New returns a pointer to a new Fpdf instance. Its methods are subsequently called to produce a single PDF document.

orientationStr specifies the default page orientation. For portrait mode, specify "P" or "Portrait". For landscape mode, specify "L" or "Landscape". An empty string will be replaced with "P".

unitStr specifies the unit of length used in size parameters for elements other than fonts, which are always measured in points. Specify "pt" for point, "mm" for millimeter, "cm" for centimeter, or "in" for inch. An empty string will be replaced with "mm".

sizeStr specifies the page size. Acceptable values are "A3", "A4", "A5", "Letter", or "Legal". An empty string will be replaced with "A4".

fontDirStr specifies the file system location in which font resources will be found. An empty string is replaced with ".". This argument only needs to reference an actual directory if a font other than one of the core fonts is used. The core fonts are "courier", "helvetica" (also called "arial"), "times", and "zapfdingbats" (also called "symbol").

func NewCustom

func NewCustom(init *InitType) (f *Fpdf)

NewCustom returns a pointer to a new Fpdf instance. Its methods are subsequently called to produce a single PDF document. NewCustom() is an alternative to New() that provides additional customization. This function is demonstrated in tutorial 15.

func (*Fpdf) AddChild

func (f *Fpdf) AddChild(parentId int, childId int)

AddChild defines a layer to other later as child layer. Parent layer will become folder of layers.

Layers are demonstrated in tutorial 26.

func (*Fpdf) AddFont

func (f *Fpdf) AddFont(familyStr, styleStr, fileStr string)

AddFont imports a TrueType, OpenType or Type1 font and makes it available. It is necessary to generate a font definition file first with the makefont utility. It is not necessary to call this function for the core PDF fonts (courier, helvetica, times, zapfdingbats).

The JSON definition file (and the font file itself when embedding) must be present in the font directory. If it is not found, the error "Could not include font definition file" is set.

family specifies the font family. The name can be chosen arbitrarily. If it is a standard family name, it will override the corresponding font. This string is used to subsequently set the font with the SetFont method.

style specifies the font style. Acceptable values are (case insensitive) the empty string for regular style, "B" for bold, "I" for italic, or "BI" or "IB" for bold and italic combined.

fileStr specifies the base name with ".json" extension of the font definition file to be added. The file will be loaded from the font directory specified in the call to New() or SetFontLocation().

See tutorial 7 for an example of this function.

func (*Fpdf) AddFontFromReader

func (f *Fpdf) AddFontFromReader(familyStr, styleStr string, r io.Reader)

AddFontFromReader imports a TrueType, OpenType or Type1 font and makes it available using a reader that satisifies the io.Reader interface. See AddFont for details about familyStr and styleStr.

func (*Fpdf) AddLayer

func (f *Fpdf) AddLayer(name string, visible bool) (layerID int)

AddLayer defines a layer that can be shown or hidden when the document is displayed. name specifies the layer name that the document reader will display in the layer list. visible specifies whether the layer will be initially visible. The return value is an integer ID that is used in a call to BeginLayer().

Layers are demonstrated in tutorial 26.

func (f *Fpdf) AddLink() int

AddLink creates a new internal link and returns its identifier. An internal link is a clickable area which directs to another place within the document. The identifier can then be passed to Cell(), Write(), Image() or Link(). The destination is defined with SetLink().

func (*Fpdf) AddPage

func (f *Fpdf) AddPage()

AddPage adds a new page to the document. If a page is already present, the Footer() method is called first to output the footer. Then the page is added, the current position set to the top-left corner according to the left and top margins, and Header() is called to display the header.

The font which was set before calling is automatically restored. There is no need to call SetFont() again if you want to continue with the same font. The same is true for colors and line width.

The origin of the coordinate system is at the top-left corner and increasing ordinates go downwards.

See AddPageFormat() for a version of this method that allows the page size and orientation to be different than the default.

func (*Fpdf) AddPageFormat

func (f *Fpdf) AddPageFormat(orientationStr string, size SizeType)

AddPageFormat adds a new page with non-default orientation or size. See AddPage() for more details.

See New() for a description of orientationStr.

size specifies the size of the new page in the units established in New().

This function is demonstrated in tutorial 15.

func (*Fpdf) AliasNbPages

func (f *Fpdf) AliasNbPages(aliasStr string)

AliasNbPages defines an alias for the total number of pages. It will be substituted as the document is closed. An empty string is replaced with the string "{nb}". This method is demonstrated in tutorial 2.

func (*Fpdf) Arc

func (f *Fpdf) Arc(x, y, rx, ry, degRotate, degStart, degEnd float64, styleStr string)

Arc draws an elliptical arc centered at point (x, y). rx and ry specify its horizontal and vertical radii.

degRotate specifies the angle that the arc will be rotated. degStart and degEnd specify the starting and ending angle of the arc. All angles are specified in degrees and measured counter-clockwise from the 3 o'clock position.

styleStr can be "F" for filled, "D" for outlined only, or "DF" or "FD" for outlined and filled. An empty string will be replaced with "D". Drawing uses the current draw color, line width, and cap style centered on the arc's path. Filling uses the current fill color.

See tutorial 11 for an example of this function.

func (*Fpdf) BeginLayer

func (f *Fpdf) BeginLayer(id int)

BeginLayer is called to begin adding content to the specified layer. All content added to the page between a call to BeginLayer and a call to EndLayer is added to the layer specified by id. See AddLayer for more details.

func (*Fpdf) Beziergon

func (f *Fpdf) Beziergon(points []PointType, styleStr string)

Beziergon draws a closed figure defined by a series of cubic Bézier curve segments. The first point in the slice defines the starting point of the figure. Each three following points p1, p2, p3 represent a curve segment to the point p3 using p1 and p2 as the Bézier control points.

The x and y fields of the points use the units established in New().

styleStr can be "F" for filled, "D" for outlined only, or "DF" or "FD" for outlined and filled. An empty string will be replaced with "D". Drawing uses the current draw color and line width centered on the ellipse's perimeter. Filling uses the current fill color.

See tutorial 28 for an example of this function.

func (*Fpdf) Bookmark

func (f *Fpdf) Bookmark(txtStr string, level int, y float64)

Bookmark sets a bookmark that will be displayed in a sidebar outline. txtStr is the title of the bookmark. level specifies the level of the bookmark in the outline; 0 is the top level, 1 is just below, and so on. y specifies the vertical position of the bookmark destination in the current page; -1 indicates the current position.

See tutorial 16 for an bookmark example.

func (*Fpdf) Cell

func (f *Fpdf) Cell(w, h float64, txtStr string)

Cell is a simpler version of CellFormat with no fill, border, links or special alignment.

func (*Fpdf) CellFormat

func (f *Fpdf) CellFormat(w, h float64, txtStr string, borderStr string, ln int, alignStr string, fill bool, link int, linkStr string)

CellFormat prints a rectangular cell with optional borders, background color and character string. The upper-left corner of the cell corresponds to the current position. The text can be aligned or centered. After the call, the current position moves to the right or to the next line. It is possible to put a link on the text.

If automatic page breaking is enabled and the cell goes beyond the limit, a page break is done before outputting.

w and h specify the width and height of the cell. If w is 0, the cell extends up to the right margin. Specifying 0 for h will result in no output, but the current position will be advanced by w.

txtStr specifies the text to display.

borderStr specifies how the cell border will be drawn. An empty string indicates no border, "1" indicates a full border, and one or more of "L", "T", "R" and "B" indicate the left, top, right and bottom sides of the border.

ln indicates where the current position should go after the call. Possible values are 0 (to the right), 1 (to the beginning of the next line), and 2 (below). Putting 1 is equivalent to putting 0 and calling Ln() just after.

alignStr specifies how the text is to be positionined within the cell. Horizontal alignment is controlled by including "L", "C" or "R" (left, center, right) in alignStr. Vertical alignment is controlled by including "T", "M" or "B" (top, middle, bottom) in alignStr. The default alignment is left middle.

fill is true to paint the cell background or false to leave it transparent.

link is the identifier returned by AddLink() or 0 for no internal link.

linkStr is a target URL or empty for no external link. A non--zero value for link takes precedence over linkStr.

See tutorial 21 for a demonstration of text alignment within a cell.

func (*Fpdf) Cellf

func (f *Fpdf) Cellf(w, h float64, fmtStr string, args ...interface{})

Cellf is a simpler printf-style version of CellFormat with no fill, border, links or special alignment. See documentation for the fmt package for details on fmtStr and args.

func (*Fpdf) Circle

func (f *Fpdf) Circle(x, y, r float64, styleStr string)

Circle draws a circle centered on point (x, y) with radius r.

styleStr can be "F" for filled, "D" for outlined only, or "DF" or "FD" for outlined and filled. An empty string will be replaced with "D". Drawing uses the current draw color and line width centered on the circle's perimeter. Filling uses the current fill color.

See tutorial 11 for an example of this function.

func (*Fpdf) ClipCircle

func (f *Fpdf) ClipCircle(x, y, r float64, outline bool)

ClipCircle begins a circular clipping operation. The circle is centered at (x, y) and has radius r. outline is true to draw a border with the current draw color and line width centered on the circle's perimeter. Only the outer half of the border will be shown. After calling this method, all rendering operations (for example, Image(), LinearGradient(), etc) will be clipped by the specified circle. Call ClipEnd() to restore unclipped operations.

See tutorial 14 for an example of this function.

func (*Fpdf) ClipEllipse

func (f *Fpdf) ClipEllipse(x, y, rx, ry float64, outline bool)

ClipEllipse begins an elliptical clipping operation. The ellipse is centered at (x, y). Its horizontal and vertical radii are specified by rx and ry. outline is true to draw a border with the current draw color and line width centered on the ellipse's perimeter. Only the outer half of the border will be shown. After calling this method, all rendering operations (for example, Image(), LinearGradient(), etc) will be clipped by the specified ellipse. Call ClipEnd() to restore unclipped operations.

See tutorial 14 for an example of this function.

func (*Fpdf) ClipEnd

func (f *Fpdf) ClipEnd()

ClipEnd ends a clipping operation that was started with a call to ClipRect(), ClipRoundedRect(), ClipText(), ClipEllipse(), ClipCircle() or ClipPolygon(). Clipping operations can be nested. The document cannot be successfully output while a clipping operation is active.

See tutorial 14 for an example of this function.

func (*Fpdf) ClipPolygon

func (f *Fpdf) ClipPolygon(points []PointType, outline bool)

ClipPolygon begins a clipping operation within a polygon. The figure is defined by a series of vertices specified by points. The x and y fields of the points use the units established in New(). The last point in the slice will be implicitly joined to the first to close the polygon. outline is true to draw a border with the current draw color and line width centered on the polygon's perimeter. Only the outer half of the border will be shown. After calling this method, all rendering operations (for example, Image(), LinearGradient(), etc) will be clipped by the specified polygon. Call ClipEnd() to restore unclipped operations.

See tutorial 14 for an example of this function.

func (*Fpdf) ClipRect

func (f *Fpdf) ClipRect(x, y, w, h float64, outline bool)

ClipRect begins a rectangular clipping operation. The rectangle is of width w and height h. Its upper left corner is positioned at point (x, y). outline is true to draw a border with the current draw color and line width centered on the rectangle's perimeter. Only the outer half of the border will be shown. After calling this method, all rendering operations (for example, Image(), LinearGradient(), etc) will be clipped by the specified rectangle. Call ClipEnd() to restore unclipped operations.

See tutorial 14 for an example of this function.

func (*Fpdf) ClipRoundedRect

func (f *Fpdf) ClipRoundedRect(x, y, w, h, r float64, outline bool)

ClipRoundedRect begins a rectangular clipping operation. The rectangle is of width w and height h. Its upper left corner is positioned at point (x, y). The rounded corners of the rectangle are specified by radius r. outline is true to draw a border with the current draw color and line width centered on the rectangle's perimeter. Only the outer half of the border will be shown. After calling this method, all rendering operations (for example, Image(), LinearGradient(), etc) will be clipped by the specified rectangle. Call ClipEnd() to restore unclipped operations.

See tutorial 14 for an example of this function.

func (*Fpdf) ClipText

func (f *Fpdf) ClipText(x, y float64, txtStr string, outline bool)

ClipText begins a clipping operation in which rendering is confined to the character string specified by txtStr. The origin (x, y) is on the left of the first character at the baseline. The current font is used. outline is true to draw a border with the current draw color and line width centered on the perimeters of the text characters. Only the outer half of the border will be shown. After calling this method, all rendering operations (for example, Image(), LinearGradient(), etc) will be clipped. Call ClipEnd() to restore unclipped operations.

See tutorial 14 for an example of this function.

func (*Fpdf) Close

func (f *Fpdf) Close()

Close terminates the PDF document. It is not necessary to call this method explicitly because Output(), OutputAndClose() and OutputFileAndClose() do it automatically. If the document contains no page, AddPage() is called to prevent the generation of an invalid document.

func (*Fpdf) Curve

func (f *Fpdf) Curve(x0, y0, cx, cy, x1, y1 float64, styleStr string)

Curve draws a single-segment quadratic Bézier curve. The curve starts at the point (x0, y0) and ends at the point (x1, y1). The control point (cx, cy) specifies the curvature. At the start point, the curve is tangent to the straight line between the start point and the control point. At the end point, the curve is tangent to the straight line between the end point and the control point.

styleStr can be "F" for filled, "D" for outlined only, or "DF" or "FD" for outlined and filled. An empty string will be replaced with "D". Drawing uses the current draw color, line width, and cap style centered on the curve's path. Filling uses the current fill color.

See tutorial 11 for an example of this function.

func (*Fpdf) CurveBezierCubic

func (f *Fpdf) CurveBezierCubic(x0, y0, cx0, cy0, cx1, cy1, x1, y1 float64, styleStr string)

CurveBezierCubic draws a single-segment cubic Bézier curve. The curve starts at the point (x0, y0) and ends at the point (x1, y1). The control points (cx0, cy0) and (cx1, cy1) specify the curvature. At the start point, the curve is tangent to the straight line between the start point and the control point (cx0, cy0). At the end point, the curve is tangent to the straight line between the end point and the control point (cx1, cy1).

styleStr can be "F" for filled, "D" for outlined only, or "DF" or "FD" for outlined and filled. An empty string will be replaced with "D". Drawing uses the current draw color, line width, and cap style centered on the curve's path. Filling uses the current fill color.

This routine performs the same function as CurveCubic() but uses standard argument order.

See tutorial 11 for examples of this function.

func (*Fpdf) CurveCubic

func (f *Fpdf) CurveCubic(x0, y0, cx0, cy0, x1, y1, cx1, cy1 float64, styleStr string)

CurveCubic draws a single-segment cubic Bézier curve. This routine performs the same function as CurveBezierCubic() but has a nonstandard argument order. It is retained to preserve backward compatibility.

func (*Fpdf) Ellipse

func (f *Fpdf) Ellipse(x, y, rx, ry, degRotate float64, styleStr string)

Ellipse draws an ellipse centered at point (x, y). rx and ry specify its horizontal and vertical radii.

degRotate specifies the counter-clockwise angle in degrees that the ellipse will be rotated.

styleStr can be "F" for filled, "D" for outlined only, or "DF" or "FD" for outlined and filled. An empty string will be replaced with "D". Drawing uses the current draw color and line width centered on the ellipse's perimeter. Filling uses the current fill color.

See tutorial 11 for an example of this function.

func (*Fpdf) EndLayer

func (f *Fpdf) EndLayer()

EndLayer is called to stop adding content to the currently active layer. See BeginLayer for more details.

func (*Fpdf) Err

func (f *Fpdf) Err() bool

Err returns true if a processing error has occurred.

func (*Fpdf) Error

func (f *Fpdf) Error() error

Error returns the internal Fpdf error; this will be nil if no error has occurred.

func (*Fpdf) GetCellMargin

func (f *Fpdf) GetCellMargin() float64

GetCellMargin returns the cell margin. This is the amount of space before and after the text within a cell that's left blank, and is in units passed to New(). It defaults to 1mm.

func (*Fpdf) GetDrawColor

func (f *Fpdf) GetDrawColor() (int, int, int)

GetDrawColor returns the current draw color as RGB components (0 - 255).

func (*Fpdf) GetFillColor

func (f *Fpdf) GetFillColor() (int, int, int)

GetFillColor returns the current fill color as RGB components (0 - 255).

func (*Fpdf) GetFontSize

func (f *Fpdf) GetFontSize() (ptSize, unitSize float64)

GetFontSize returns the size of the current font in points followed by the size in the unit of measure specified in New(). The second value can be used as a line height value in drawing operations.

func (*Fpdf) GetLineWidth

func (f *Fpdf) GetLineWidth() float64

GetLineWidth returns the current line thickness.

func (*Fpdf) GetMargins

func (f *Fpdf) GetMargins() (left, top, right, bottom float64)

GetMargins returns the left, top, right, and bottom margins. The first three are set with the SetMargins() method. The bottom margin is set with the SetAutoPageBreak() method.

func (*Fpdf) GetPageSize

func (f *Fpdf) GetPageSize() (width, height float64)

GetPageSize returns the current page's width and height. This is the paper's size. To compute the size of the area being used, subtract the margins (see GetMargins()).

func (*Fpdf) GetStringWidth

func (f *Fpdf) GetStringWidth(s string) float64

GetStringWidth returns the length of a string in user units. A font must be currently selected.

Example
pdf := gofpdf.New("", "", "", cnFontDir)
pdf.SetFont("Helvetica", "", 12)
pdf.AddPage()
for _, s := range []string{"Hello", "世界", "\xe7a va?"} {
	fmt.Printf("%-32s width %5.2f, bytes %2d, runes %2d\n",
		hexStr(s), pdf.GetStringWidth(s), len(s), len([]rune(s)))
	if pdf.Err() {
		fmt.Println(pdf.Error())
	}
}
pdf.Close()
Output:

"\x48\x65\x6c\x6c\x6f":          width  9.64, bytes  5, runes  5
"\xe4\xb8\x96\xe7\x95\x8c":      width 13.95, bytes  6, runes  2
"\xe7\x61\x20\x76\x61\x3f":      width 12.47, bytes  6, runes  6

func (*Fpdf) GetTextColor

func (f *Fpdf) GetTextColor() (int, int, int)

GetTextColor returns the current text color as RGB components (0 - 255).

func (*Fpdf) GetX

func (f *Fpdf) GetX() float64

GetX returns the abscissa of the current position.

Note: the value returned will be affected by the current cell margin. To account for this, you may need to either add the value returned by GetCellMargin() to it or call SetCellMargin(0) to remove the cell margin.

func (*Fpdf) GetXY

func (f *Fpdf) GetXY() (float64, float64)

GetXY returns the abscissa and ordinate of the current position.

Note: the value returned for the abscissa will be affected by the current cell margin. To account for this, you may need to either add the value returned by GetCellMargin() to it or call SetCellMargin(0) to remove the cell margin.

func (*Fpdf) GetY

func (f *Fpdf) GetY() float64

GetY returns the ordinate of the current position.

func (*Fpdf) HTMLBasicNew

func (f *Fpdf) HTMLBasicNew() (html HTMLBasicType)

HTMLBasicNew returns an instance that facilitates writing basic HTML in the specified PDF file.

This function is demonstrated in tutorial 6.

func (*Fpdf) Image

func (f *Fpdf) Image(imageNameStr string, x, y, w, h float64, flow bool, tp string, link int, linkStr string)

Image puts a JPEG, PNG or GIF image in the current page. The size it will take on the page can be specified in different ways. If both w and h are 0, the image is rendered at 96 dpi. If either w or h is zero, it will be calculated from the other dimension so that the aspect ratio is maintained. If w and h are negative, their absolute values indicate their dpi extents.

Supported JPEG formats are 24 bit, 32 bit and gray scale. Supported PNG formats are 24 bit, indexed color, and 8 bit indexed gray scale. If a GIF image is animated, only the first frame is rendered. Transparency is supported. It is possible to put a link on the image.

imageNameStr may be the name of an image as registered with a call to either RegisterImageReader() or RegisterImage(). In the first case, the image is loaded using an io.Reader. This is generally useful when the image is obtained from some other means than as a disk-based file. In the second case, the image is loaded as a file. Alternatively, imageNameStr may directly specify a sufficiently qualified filename.

However the image is loaded, if it is used more than once only one copy is embedded in the file.

If x is negative, the current abscissa is used.

If flow is true, the current y value is advanced after placing the image and a page break may be made if necessary.

tp specifies the image format. Possible values are (case insensitive): "JPG", "JPEG", "PNG" and "GIF". If not specified, the type is inferred from the file extension.

If link refers to an internal page anchor (that is, it is non-zero; see AddLink()), the image will be a clickable internal link. Otherwise, if linkStr specifies a URL, the image will be a clickable external link.

func (*Fpdf) ImageTypeFromMime

func (f *Fpdf) ImageTypeFromMime(mimeStr string) (tp string)

ImageTypeFromMime returns the image type used in various image-related functions (for example, Image()) that is associated with the specified MIME type. For example, "jpg" is returned if mimeStr is "image/jpeg". An error is set if the specified MIME type is not supported.

func (*Fpdf) Line

func (f *Fpdf) Line(x1, y1, x2, y2 float64)

Line draws a line between points (x1, y1) and (x2, y2) using the current draw color, line width and cap style.

func (*Fpdf) LinearGradient

func (f *Fpdf) LinearGradient(x, y, w, h float64, r1, g1, b1 int, r2, g2, b2 int, x1, y1, x2, y2 float64)

LinearGradient draws a rectangular area with a blending of one color to another. The rectangle is of width w and height h. Its upper left corner is positioned at point (x, y).

Each color is specified with three component values, one each for red, green and blue. The values range from 0 to 255. The first color is specified by (r1, g1, b1) and the second color by (r2, g2, b2).

The blending is controlled with a gradient vector that uses normalized coordinates in which the lower left corner is position (0, 0) and the upper right corner is (1, 1). The vector's origin and destination are specified by the points (x1, y1) and (x2, y2). In a linear gradient, blending occurs perpendicularly to the vector. The vector does not necessarily need to be anchored on the rectangle edge. Color 1 is used up to the origin of the vector and color 2 is used beyond the vector's end point. Between the points the colors are gradually blended.

See tutorial 13 for an example of this function.

func (f *Fpdf) Link(x, y, w, h float64, link int)

Link puts a link on a rectangular area of the page. Text or image links are generally put via Cell(), Write() or Image(), but this method can be useful for instance to define a clickable area inside an image. link is the value returned by AddLink().

func (*Fpdf) LinkString

func (f *Fpdf) LinkString(x, y, w, h float64, linkStr string)

LinkString puts a link on a rectangular area of the page. Text or image links are generally put via Cell(), Write() or Image(), but this method can be useful for instance to define a clickable area inside an image. linkStr is the target URL.

func (*Fpdf) Ln

func (f *Fpdf) Ln(h float64)

Ln performs a line break. The current abscissa goes back to the left margin and the ordinate increases by the amount passed in parameter. A negative value of h indicates the height of the last printed cell.

func (*Fpdf) MultiCell

func (f *Fpdf) MultiCell(w, h float64, txtStr, borderStr, alignStr string, fill bool)

MultiCell supports printing text with line breaks. They can be automatic (as soon as the text reaches the right border of the cell) or explicit (via the \n character). As many cells as necessary are output, one below the other.

Text can be aligned, centered or justified. The cell block can be framed and the background painted. See CellFormat() for more details.

w is the width of the cells. A value of zero indicates cells that reach to the right margin.

h indicates the line height of each cell in the unit of measure specified in New().

func (*Fpdf) Ok

func (f *Fpdf) Ok() bool

Ok returns true if no processing errors have occurred.

func (*Fpdf) OpenLayerPane

func (f *Fpdf) OpenLayerPane()

OpenLayerPane advises the document reader to open the layer pane when the document is initially displayed.

func (*Fpdf) Output

func (f *Fpdf) Output(w io.Writer) error

Output sends the PDF document to the writer specified by w. No output will take place if an error has occured in the document generation process. w remains open after this function returns. After returning, f is in a closed state and its methods should not be called.

func (*Fpdf) OutputAndClose

func (f *Fpdf) OutputAndClose(w io.WriteCloser) error

OutputAndClose sends the PDF document to the writer specified by w. This method will close both f and w, even if an error is detected and no document is produced.

func (*Fpdf) OutputFileAndClose

func (f *Fpdf) OutputFileAndClose(fileStr string) error

OutputFileAndClose creates or truncates the file specified by fileStr and writes the PDF document to it. This method will close f and the newly written file, even if an error is detected and no document is produced.

This function is demonstrated in tutorial 1.

func (*Fpdf) PageNo

func (f *Fpdf) PageNo() int

PageNo returns the current page number.

func (*Fpdf) PageSize

func (f *Fpdf) PageSize(pageNum int) (wd, ht float64, unitStr string)

PageSize returns the width and height of the specified page in the units established in New(). These return values are followed by the unit of measure itself. If pageNum is zero or otherwise out of bounds, it returns the default page size, that is, the size of the page that would be added by AddPage(). This function is demonstrated in tutorial 15.

func (*Fpdf) PointConvert

func (f *Fpdf) PointConvert(pt float64) float64

PointConvert returns the value of pt, expressed in points (1/72 inch), as a value expressed in the unit of measure specified in New(). Since font management in Fpdf uses points, this method can help with line height calculations and other methods that require user units.

func (*Fpdf) Polygon

func (f *Fpdf) Polygon(points []PointType, styleStr string)

Polygon draws a closed figure defined by a series of vertices specified by points. The x and y fields of the points use the units established in New(). The last point in the slice will be implicitly joined to the first to close the polygon.

styleStr can be "F" for filled, "D" for outlined only, or "DF" or "FD" for outlined and filled. An empty string will be replaced with "D". Drawing uses the current draw color and line width centered on the ellipse's perimeter. Filling uses the current fill color.

See tutorial 25 for an example of this function.

func (*Fpdf) RadialGradient

func (f *Fpdf) RadialGradient(x, y, w, h float64, r1, g1, b1 int, r2, g2, b2 int, x1, y1, x2, y2, r float64)

RadialGradient draws a rectangular area with a blending of one color to another. The rectangle is of width w and height h. Its upper left corner is positioned at point (x, y).

Each color is specified with three component values, one each for red, green and blue. The values range from 0 to 255. The first color is specified by (r1, g1, b1) and the second color by (r2, g2, b2).

The blending is controlled with a point and a circle, both specified with normalized coordinates in which the lower left corner of the rendered rectangle is position (0, 0) and the upper right corner is (1, 1). Color 1 begins at the origin point specified by (x1, y1). Color 2 begins at the circle specified by the center point (x2, y2) and radius r. Colors are gradually blended from the origin to the circle. The origin and the circle's center do not necessarily have to coincide, but the origin must be within the circle to avoid rendering problems.

See tutorial 13 for an example of this function.

func (*Fpdf) Rect

func (f *Fpdf) Rect(x, y, w, h float64, styleStr string)

Rect outputs a rectangle of width w and height h with the upper left corner positioned at point (x, y).

It can be drawn (border only), filled (with no border) or both. styleStr can be "F" for filled, "D" for outlined only, or "DF" or "FD" for outlined and filled. An empty string will be replaced with "D". Drawing uses the current draw color and line width centered on the rectangle's perimeter. Filling uses the current fill color.

func (*Fpdf) RegisterImage

func (f *Fpdf) RegisterImage(fileStr, tp string) (info *ImageInfoType)

RegisterImage registers an image, adding it to the PDF file but not adding it to the page. Use Image() with the same filename to add the image to the page. Note that Image() calls this function, so this function is only necessary if you need information about the image before placing it. See Image() for restrictions on the image and the "tp" parameters.

See tutorial 18 for an example of this function.

func (*Fpdf) RegisterImageReader

func (f *Fpdf) RegisterImageReader(imgName, tp string, r io.Reader) (info *ImageInfoType)

RegisterImageReader registers an image, reading it from Reader r, adding it to the PDF file but not adding it to the page. Use Image() with the same name to add the image to the page. Note that tp should be specified in this case.

See Image() for restrictions on the image and the "tp" parameters.

See tutorial 27 for an example of how this function can be used to load an image from the web.

func (*Fpdf) SVGBasicWrite

func (f *Fpdf) SVGBasicWrite(sb *SVGBasicType, scale float64)

SVGBasicWrite renders the paths encoded in the basic SVG image specified by sb. The scale value is used to convert the coordinates in the path to the unit of measure specified in New(). The current position (as set with a call to SetXY()) is used as the origin of the image. The current line cap style (as set with SetLineCapStyle()), line width (as set with SetLineWidth()), and draw color (as set with SetDrawColor()) are used in drawing the image paths.

See example 20 for a demonstration of this function.

func (*Fpdf) SVGWriteText

func (f *Fpdf) SVGWriteText(sb *SVGBasicType, text TextType, scale float64)

SVGWriteText writes, transform and rotate SVG text on PDF document

func (*Fpdf) SVGWriteTexts

func (f *Fpdf) SVGWriteTexts(sb *SVGBasicType, scale float64)

SVGWriteTexts writes SVG texts on PDF document

func (*Fpdf) SetAcceptPageBreakFunc

func (f *Fpdf) SetAcceptPageBreakFunc(fnc func() bool)

SetAcceptPageBreakFunc allows the application to control where page breaks occur.

fnc is an application function (typically a closure) that is called by the library whenever a page break condition is met. The break is issued if true is returned. The default implementation returns a value according to the mode selected by SetAutoPageBreak. The function provided should not be called by the application.

See tutorial 4 for an example of how this function can be used to manage multiple columns.

func (*Fpdf) SetAlpha

func (f *Fpdf) SetAlpha(alpha float64, blendModeStr string)

SetAlpha sets the alpha blending channel. The blending effect applies to text, drawings and images.

alpha must be a value between 0.0 (fully transparent) to 1.0 (fully opaque). Values outside of this range result in an error.

blendModeStr must be one of "Normal", "Multiply", "Screen", "Overlay", "Darken", "Lighten", "ColorDodge", "ColorBurn","HardLight", "SoftLight", "Difference", "Exclusion", "Hue", "Saturation", "Color", or "Luminosity". An empty string is replaced with "Normal".

To reset normal rendering after applying a blending mode, call this method with alpha set to 1.0 and blendModeStr set to "Normal".

See tutorial 12 for an example of this function, including samples of each blending mode.

func (*Fpdf) SetAuthor

func (f *Fpdf) SetAuthor(authorStr string, isUTF8 bool)

SetAuthor defines the author of the document. isUTF8 indicates if the string is encoded in ISO-8859-1 (false) or UTF-8 (true).

func (*Fpdf) SetAutoPageBreak

func (f *Fpdf) SetAutoPageBreak(auto bool, margin float64)

SetAutoPageBreak enables or disables the automatic page breaking mode. When enabling, the second parameter is the distance from the bottom of the page that defines the triggering limit. By default, the mode is on and the margin is 2 cm.

func (*Fpdf) SetCellMargin

func (f *Fpdf) SetCellMargin(margin float64)

SetCellMargin sets the cell margin. This is the amount of space before and after the text within a cell that's left blank, and is in units passed to New().

func (*Fpdf) SetCompression

func (f *Fpdf) SetCompression(compress bool)

SetCompression activates or deactivates page compression with zlib. When activated, the internal representation of each page is compressed, which leads to a compression ratio of about 2 for the resulting document. Compression is on by default.

func (*Fpdf) SetCreator

func (f *Fpdf) SetCreator(creatorStr string, isUTF8 bool)

SetCreator defines the creator of the document. isUTF8 indicates if the string is encoded in ISO-8859-1 (false) or UTF-8 (true).

func (*Fpdf) SetDisplayMode

func (f *Fpdf) SetDisplayMode(zoomStr, layoutStr string)

SetDisplayMode sets advisory display directives for the document viewer. Pages can be displayed entirely on screen, occupy the full width of the window, use real size, be scaled by a specific zooming factor or use viewer default (configured in the Preferences menu of Adobe Reader). The page layout can be specified so that pages are displayed individually or in pairs.

zoomStr can be "fullpage" to display the entire page on screen, "fullwidth" to use maximum width of window, "real" to use real size (equivalent to 100% zoom) or "default" to use viewer default mode.

layoutStr can be "single" (or "SinglePage") to display one page at once, "continuous" (or "OneColumn") to display pages continuously, "two" (or "TwoColumnLeft") to display two pages on two columns with odd-numbered pages on the left, or "TwoColumnRight" to display two pages on two columns with odd-numbered pages on the right, or "TwoPageLeft" to display pages two at a time with odd-numbered pages on the left, or "TwoPageRight" to display pages two at a time with odd-numbered pages on the right, or "default" to use viewer default mode.

func (*Fpdf) SetDrawColor

func (f *Fpdf) SetDrawColor(r, g, b int)

SetDrawColor defines the color used for all drawing operations (lines, rectangles and cell borders). It is expressed in RGB components (0 - 255). The method can be called before the first page is created. The value is retained from page to page.

func (*Fpdf) SetError

func (f *Fpdf) SetError(err error)

SetError sets an error to halt PDF generation. This may facilitate error handling by application. See also Ok(), Err() and Error().

func (*Fpdf) SetErrorf

func (f *Fpdf) SetErrorf(fmtStr string, args ...interface{})

SetErrorf sets the internal Fpdf error with formatted text to halt PDF generation; this may facilitate error handling by application. If an error condition is already set, this call is ignored.

See the documentation for printing in the standard fmt package for details about fmtStr and args.

func (*Fpdf) SetFillColor

func (f *Fpdf) SetFillColor(r, g, b int)

SetFillColor defines the color used for all filling operations (filled rectangles and cell backgrounds). It is expressed in RGB components (0 -255). The method can be called before the first page is created and the value is retained from page to page.

func (*Fpdf) SetFont

func (f *Fpdf) SetFont(familyStr, styleStr string, size float64)

SetFont sets the font used to print character strings. It is mandatory to call this method at least once before printing text or the resulting document will not be valid.

The font can be either a standard one or a font added via the AddFont() method or AddFontFromReader() method. Standard fonts use the Windows encoding cp1252 (Western Europe).

The method can be called before the first page is created and the font is kept from page to page. If you just wish to change the current font size, it is simpler to call SetFontSize().

Note: the font definition file must be accessible. An error is set if the file cannot be read.

familyStr specifies the font family. It can be either a name defined by AddFont(), AddFontFromReader() or one of the standard families (case insensitive): "Courier" for fixed-width, "Helvetica" or "Arial" for sans serif, "Times" for serif, "Symbol" or "ZapfDingbats" for symbolic.

styleStr can be "B" (bold), "I" (italic), "U" (underscore) or any combination. The default value (specified with an empty string) is regular. Bold and italic styles do not apply to Symbol and ZapfDingbats.

size is the font size measured in points. The default value is the current size. If no size has been specified since the beginning of the document, the value taken is 12.

func (*Fpdf) SetFontLocation

func (f *Fpdf) SetFontLocation(fontDirStr string)

SetFontLocation sets the location in the file system of the font and font definition files.

func (*Fpdf) SetFontSize

func (f *Fpdf) SetFontSize(size float64)

SetFontSize defines the size of the current font in points.

func (*Fpdf) SetFooterFunc

func (f *Fpdf) SetFooterFunc(fnc func())

SetFooterFunc sets the function that lets the application render the page footer. The specified function is automatically called by AddPage() and Close() and should not be called directly by the application. The implementation in Fpdf is empty, so you have to provide an appropriate function if you want page footers. fnc will typically be a closure that has access to the Fpdf instance and other document generation variables.

func (*Fpdf) SetHeaderFunc

func (f *Fpdf) SetHeaderFunc(fnc func())

SetHeaderFunc sets the function that lets the application render the page header. The specified function is automatically called by AddPage() and should not be called directly by the application. The implementation in Fpdf is empty, so you have to provide an appropriate function if you want page headers. fnc will typically be a closure that has access to the Fpdf instance and other document generation variables.

func (*Fpdf) SetKeywords

func (f *Fpdf) SetKeywords(keywordsStr string, isUTF8 bool)

SetKeywords defines the keywords of the document. keywordStr is a space-delimited string, for example "invoice August". isUTF8 indicates if the string is encoded

func (*Fpdf) SetLeftMargin

func (f *Fpdf) SetLeftMargin(margin float64)

SetLeftMargin defines the left margin. The method can be called before creating the first page. If the current abscissa gets out of page, it is brought back to the margin.

func (*Fpdf) SetLineCapStyle

func (f *Fpdf) SetLineCapStyle(styleStr string)

SetLineCapStyle defines the line cap style. styleStr should be "butt", "round" or "square". A square style projects from the end of the line. The method can be called before the first page is created. The value is retained from page to page.

func (*Fpdf) SetLineWidth

func (f *Fpdf) SetLineWidth(width float64)

SetLineWidth defines the line width. By default, the value equals 0.2 mm. The method can be called before the first page is created. The value is retained from page to page.

func (f *Fpdf) SetLink(link int, y float64, page int)

SetLink defines the page and position a link points to. See AddLink().

func (*Fpdf) SetMargins

func (f *Fpdf) SetMargins(left, top, right float64)

SetMargins defines the left, top and right margins. By default, they equal 1 cm. Call this method to change them. If the value of the right margin is less than zero, it is set to the same as the left margin.

func (*Fpdf) SetProtection

func (f *Fpdf) SetProtection(actionFlag byte, userPassStr, ownerPassStr string)

SetProtection applies certain constraints on the finished PDF document.

actionFlag is a bitflag that controls various document operations. CnProtectPrint allows the document to be printed. CnProtectModify allows a document to be modified by a PDF editor. CnProtectCopy allows text and images to be copied into the system clipboard. CnProtectAnnotForms allows annotations and forms to be added by a PDF editor. These values can be combined by or-ing them together, for example, CnProtectCopy|CnProtectModify. This flag is advisory; not all PDF readers implement the constraints that this argument attempts to control.

userPassStr specifies the password that will need to be provided to view the contents of the PDF. The permissions specified by actionFlag will apply.

ownerPassStr specifies the password that will need to be provided to gain full access to the document regardless of the actionFlag value. An empty string for this argument will be replaced with a random value, effectively prohibiting full access to the document.

See tutorial 24 for an example of this function.

func (*Fpdf) SetRightMargin

func (f *Fpdf) SetRightMargin(margin float64)

SetRightMargin defines the right margin. The method can be called before creating the first page.

func (*Fpdf) SetStyle

func (f *Fpdf) SetStyle(style *StyleDef)

SetStyle sets style (color, line width etc.) for current PDF file from StyleDef

func (*Fpdf) SetSubject

func (f *Fpdf) SetSubject(subjectStr string, isUTF8 bool)

SetSubject defines the subject of the document. isUTF8 indicates if the string is encoded in ISO-8859-1 (false) or UTF-8 (true).

func (*Fpdf) SetTextColor

func (f *Fpdf) SetTextColor(r, g, b int)

SetTextColor defines the color used for text. It is expressed in RGB components (0 - 255). The method can be called before the first page is created. The value is retained from page to page.

func (*Fpdf) SetTitle

func (f *Fpdf) SetTitle(titleStr string, isUTF8 bool)

SetTitle defines the title of the document. isUTF8 indicates if the string is encoded in ISO-8859-1 (false) or UTF-8 (true).

func (*Fpdf) SetTopMargin

func (f *Fpdf) SetTopMargin(margin float64)

SetTopMargin defines the top margin. The method can be called before creating the first page.

func (*Fpdf) SetX

func (f *Fpdf) SetX(x float64)

SetX defines the abscissa of the current position. If the passed value is negative, it is relative to the right of the page.

func (*Fpdf) SetXY

func (f *Fpdf) SetXY(x, y float64)

SetXY defines the abscissa and ordinate of the current position. If the passed values are negative, they are relative respectively to the right and bottom of the page.

func (*Fpdf) SetY

func (f *Fpdf) SetY(y float64)

SetY moves the current abscissa back to the left margin and sets the ordinate. If the passed value is negative, it is relative to the bottom of the page.

func (*Fpdf) SplitLines

func (f *Fpdf) SplitLines(txt []byte, w float64) [][]byte

SplitLines splits text into several lines using the current font. Each line has its length limited to a maximum width given by w. This function can be used to determine the total height of wrapped text for vertical placement purposes.

You can use MultiCell if you want to print a text on several lines in a simple way.

See tutorial 19 for an example of this function.

func (*Fpdf) String

func (f *Fpdf) String() string

String satisfies the fmt.Stringer interface and summarizes the Fpdf instance.

func (*Fpdf) Text

func (f *Fpdf) Text(x, y float64, txtStr string)

Text prints a character string. The origin (x, y) is on the left of the first character at the baseline. This method permits a string to be placed precisely on the page, but it is usually easier to use Cell(), MultiCell() or Write() which are the standard methods to print text.

func (*Fpdf) Transform

func (f *Fpdf) Transform(tm TransformMatrix)

Transform generally transforms the following text, drawings and images according to the specified matrix. It is typically easier to use the various methods such as TransformRotate() and TransformMirrorVertical() instead.

func (*Fpdf) TransformBegin

func (f *Fpdf) TransformBegin()

TransformBegin sets up a transformation context for subsequent text, drawings and images. The typical usage is to immediately follow a call to this method with a call to one or more of the transformation methods such as TransformScale(), TransformSkew(), etc. This is followed by text, drawing or image output and finally a call to TransformEnd(). All transformation contexts must be properly ended prior to outputting the document.

See tutorial 17 for transformation examples.

func (*Fpdf) TransformEnd

func (f *Fpdf) TransformEnd()

TransformEnd applies a transformation that was begun with a call to TransformBegin().

func (*Fpdf) TransformMirrorHorizontal

func (f *Fpdf) TransformMirrorHorizontal(x float64)

TransformMirrorHorizontal horizontally mirrors the following text, drawings and images. x is the axis of reflection.

func (*Fpdf) TransformMirrorLine

func (f *Fpdf) TransformMirrorLine(angle, x, y float64)

TransformMirrorLine symmetrically mirrors the following text, drawings and images on the line defined by angle and the point (x, y). angles is specified in degrees and measured counter-clockwise from the 3 o'clock position.

func (*Fpdf) TransformMirrorPoint

func (f *Fpdf) TransformMirrorPoint(x, y float64)

TransformMirrorPoint symmetrically mirrors the following text, drawings and images on the point specified by (x, y).

func (*Fpdf) TransformMirrorVertical

func (f *Fpdf) TransformMirrorVertical(y float64)

TransformMirrorVertical vertically mirrors the following text, drawings and images. y is the axis of reflection.

func (*Fpdf) TransformRotate

func (f *Fpdf) TransformRotate(angle, x, y float64)

TransformRotate rotates the following text, drawings and images around the center point (x, y). angle is specified in degrees and measured counter-clockwise from the 3 o'clock position.

func (*Fpdf) TransformScale

func (f *Fpdf) TransformScale(scaleWd, scaleHt, x, y float64)

TransformScale generally scales the following text, drawings and images. scaleWd and scaleHt are the percentage scaling factors for width and height. (x, y) is center of scaling.

func (*Fpdf) TransformScaleX

func (f *Fpdf) TransformScaleX(scaleWd, x, y float64)

TransformScaleX scales the width of the following text, drawings and images. scaleWd is the percentage scaling factor. (x, y) is center of scaling.

func (*Fpdf) TransformScaleXY

func (f *Fpdf) TransformScaleXY(s, x, y float64)

TransformScaleXY uniformly scales the width and height of the following text, drawings and images. s is the percentage scaling factor for both width and height. (x, y) is center of scaling.

func (*Fpdf) TransformScaleY

func (f *Fpdf) TransformScaleY(scaleHt, x, y float64)

TransformScaleY scales the height of the following text, drawings and images. scaleHt is the percentage scaling factor. (x, y) is center of scaling.

func (*Fpdf) TransformSkew

func (f *Fpdf) TransformSkew(angleX, angleY, x, y float64)

TransformSkew generally skews the following text, drawings and images keeping the point (x, y) stationary. angleX ranges from -90 degrees (skew to the left) to 90 degrees (skew to the right). angleY ranges from -90 degrees (skew to the bottom) to 90 degrees (skew to the top).

func (*Fpdf) TransformSkewX

func (f *Fpdf) TransformSkewX(angleX, x, y float64)

TransformSkewX horizontally skews the following text, drawings and images keeping the point (x, y) stationary. angleX ranges from -90 degrees (skew to the left) to 90 degrees (skew to the right).

func (*Fpdf) TransformSkewY

func (f *Fpdf) TransformSkewY(angleY, x, y float64)

TransformSkewY vertically skews the following text, drawings and images keeping the point (x, y) stationary. angleY ranges from -90 degrees (skew to the bottom) to 90 degrees (skew to the top).

func (*Fpdf) TransformTranslate

func (f *Fpdf) TransformTranslate(tx, ty float64)

TransformTranslate moves the following text, drawings and images horizontally and vertically by the amounts specified by tx and ty.

func (*Fpdf) TransformTranslateX

func (f *Fpdf) TransformTranslateX(tx float64)

TransformTranslateX moves the following text, drawings and images horizontally by the amount specified by tx.

func (*Fpdf) TransformTranslateY

func (f *Fpdf) TransformTranslateY(ty float64)

TransformTranslateY moves the following text, drawings and images vertically by the amount specified by ty.

func (*Fpdf) UnicodeTranslatorFromDescriptor

func (f *Fpdf) UnicodeTranslatorFromDescriptor(cpStr string) (rep func(string) string)

UnicodeTranslatorFromDescriptor returns a function that can be used to translate, where possible, utf-8 strings to a form that is compatible with the specified code page. See UnicodeTranslator for more details.

cpStr identifies a code page. A descriptor file in the font directory, set with the fontDirStr argument in the call to New(), should have this name plus the extension ".map". If cpStr is empty, it will be replaced with "cp1252", the gofpdf code page default.

If an error occurs reading the descriptor, the returned function is valid but does not perform any rune translation.

See tutorial 23 for an example of this function.

func (*Fpdf) Write

func (f *Fpdf) Write(h float64, txtStr string)

Write prints text from the current position. When the right margin is reached (or the \n character is met) a line break occurs and text continues from the left margin. Upon method exit, the current position is left just at the end of the text.

It is possible to put a link on the text.

h indicates the line height in the unit of measure specified in New().

func (*Fpdf) WriteLinkID

func (f *Fpdf) WriteLinkID(h float64, displayStr string, linkID int)

WriteLinkID writes text that when clicked jumps to another location in the PDF. linkID is an identifier returned by AddLink(). See Write() for argument details.

func (*Fpdf) WriteLinkString

func (f *Fpdf) WriteLinkString(h float64, displayStr, targetStr string)

WriteLinkString writes text that when clicked launches an external URL. See Write() for argument details.

func (*Fpdf) Writef

func (f *Fpdf) Writef(h float64, fmtStr string, args ...interface{})

Writef is like Write but uses printf-style formatting. See the documentation for package fmt for more details on fmtStr and args.

type HTMLBasicSegmentType

type HTMLBasicSegmentType struct {
	Cat  byte              // 'O' open tag, 'C' close tag, 'T' text
	Str  string            // Literal text unchanged, tags are lower case
	Attr map[string]string // Attribute keys are lower case
}

HTMLBasicSegmentType defines a segment of literal text in which the current attributes do not vary, or an open tag or a close tag.

func HTMLBasicTokenize

func HTMLBasicTokenize(htmlStr string) (list []HTMLBasicSegmentType)

HTMLBasicTokenize returns a list of HTML tags and literal elements. This is done with regular expressions, so the result is only marginally better than useless.

type HTMLBasicType

type HTMLBasicType struct {
	Link struct {
		ClrR, ClrG, ClrB         int
		Bold, Italic, Underscore bool
	}
	// contains filtered or unexported fields
}

HTMLBasicType is used for rendering a very basic subset of HTML. It supports only hyperlinks and bold, italic and underscore attributes. In the Link structure, the ClrR, ClrG and ClrB fields (0 through 255) define the color of hyperlinks. The Bold, Italic and Underscore values define the hyperlink style.

func (*HTMLBasicType) Write

func (html *HTMLBasicType) Write(lineHt float64, htmlStr string)

Write prints text from the current position using the currently selected font. See HTMLBasicNew() to create a receiver that is associated with the PDF document instance. The text can be encoded with a basic subset of HTML that includes hyperlinks and tags for italic (I), bold (B) and underscore (U) attributes. When the right margin is reached a line break occurs and text continues from the left margin. Upon method exit, the current position is left at the end of the text.

lineHt indicates the line height in the unit of measure specified in New().

type ImageInfoType

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

ImageInfoType contains size, color and other information about an image

func (*ImageInfoType) Extent

func (info *ImageInfoType) Extent() (wd, ht float64)

Extent returns the width and height of the image in the units of the Fpdf object.

func (*ImageInfoType) Height

func (info *ImageInfoType) Height() float64

Height returns the height of the image in the units of the Fpdf object.

func (*ImageInfoType) Width

func (info *ImageInfoType) Width() float64

Width returns the width of the image in the units of the Fpdf object.

type InitType

type InitType struct {
	OrientationStr string
	UnitStr        string
	SizeStr        string
	Size           SizeType
	FontDirStr     string
}

InitType is used with NewCustom() to customize an Fpdf instance. OrientationStr, UnitStr, SizeStr and FontDirStr correspond to the arguments accepted by New(). If the Wd and Ht fields of Size are each greater than zero, Size will be used to set the default page size rather than SizeStr. Wd and Ht are specified in the units of measure indicated by UnitStr.

type Line

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

func NewLine

func NewLine(x1, y1, x2, y2 float64) *Line

func (Line) Draw

func (l Line) Draw(f *Fpdf, style *StyleDef)

func (Line) DrawDashed

func (l Line) DrawDashed(f *Fpdf, dashArray []float64)

func (Line) Length

func (l Line) Length() float64

type PointType

type PointType struct {
	X, Y float64
}

PointType fields X and Y specify the horizontal and vertical coordinates of a point, typically used in drawing.

func (PointType) XY

func (p PointType) XY() (float64, float64)

XY returns the X and Y components of the receiver point.

type SVGBasicSegmentType

type SVGBasicSegmentType struct {
	Cmd       byte // See http://www.w3.org/TR/SVG/paths.html for path command structure
	Arg       [6]float64
	Class     string
	IsPolygon bool
}

SVGBasicSegmentType describes a single curve or position segment

type SVGBasicType

type SVGBasicType struct {
	Wd, Ht   float64
	X, Y     float64
	Segments [][]SVGBasicSegmentType
	Styles   StylesDef
	Texts    []TextType
}

SVGBasicType aggregates the information needed to describe a multi-segment basic vector image

func SVGBasicFileParse

func SVGBasicFileParse(svgFileStr string) (sig SVGBasicType, err error)

SVGBasicFileParse parses a simple scalable vector graphics (SVG) file into a basic descriptor. See SVGBasicParse for additional comments and tutorial 20 for an example of this function.

func SVGBasicParse

func SVGBasicParse(buf []byte) (sig SVGBasicType, err error)

SVGBasicParse parses a simple scalable vector graphics (SVG) buffer into a descriptor. Only a small subset of the SVG standard, in particular the path information generated by jSignature, is supported. The returned path data includes only the commands 'M' (absolute moveto: x, y), 'L' (absolute lineto: x, y), and 'C' (absolute cubic Bézier curve: cx0, cy0, cx1, cy1, x1,y1).

type SizeType

type SizeType struct {
	Wd, Ht float64
}

SizeType fields Wd and Ht specify the horizontal and vertical extents of a document element such as a page.

type StyleDef

type StyleDef struct {
	StringMap     map[string]string
	DashArray     []float64
	Stroke        [3]int
	Fill          [3]int
	IsFill        bool
	IsStroke      bool
	StrokeWidth   float64
	BaseLineShift float64
	IsBold        bool
	Opacity       float64
	FontSize      float64
}

StyleDef aggregates data about element style

func NewEmptyStyleDef

func NewEmptyStyleDef() *StyleDef

NewEmptyStyleDef creates new empty StyleDef record

func NewStyleDef

func NewStyleDef(str string) *StyleDef

NewStyleDef returns new instance of StyleDef from string

func (*StyleDef) Append

func (ce *StyleDef) Append(str string)

Append adds attribute to style def

func (StyleDef) Check

func (ce StyleDef) Check(key, value string) bool

Check returns true if Style definition contains attribute equal to value

func (*StyleDef) Extend

func (ce *StyleDef) Extend(style *StyleDef)

Extend cureent styledef about data from another styledef

func (*StyleDef) Get

func (ce *StyleDef) Get(key string) (string, bool)

Get is a getter for style def

func (*StyleDef) Set

func (ce *StyleDef) Set(key, value string)

Set and parse style attribute

type StylesDef

type StylesDef map[string]*StyleDef

StylesDef stores styles for classes

func NewEmptyStylesDef

func NewEmptyStylesDef() StylesDef

NewEmptyStylesDef create new empty styles def

func NewStylesDef

func NewStylesDef(styles []string) StylesDef

NewStylesDef create new empty styles def from strings

func (StylesDef) Get

func (cd StylesDef) Get(class string) *StyleDef

Get returns existing StyleDef from key. If does not exists then creates new one add with key and returns. Search order:

  1. search for class
  2. search for "*."+class
  3. search for "text."+class
  4. return empty style def

type TextType

type TextType struct {
	Transform string
	Text      []string
	Class     string
	Style     *StyleDef
	// contains filtered or unexported fields
}

TextType aggregates informations about Text and his transformation, style, abd style class

func NewTextType

func NewTextType(src srcText) TextType

NewTextType parsing and creates new TextType from string

func (TextType) FontScale

func (t TextType) FontScale() float64

FontScale returns font scale for TextType

func (TextType) XY

func (t TextType) XY() (float64, float64)

XY returns coordinates of text

type TransformMatrix

type TransformMatrix struct {
	A, B, C, D, E, F float64
}

TransformMatrix is used for generalized transformations of text, drawings and images.

type TtfType

type TtfType struct {
	Embeddable             bool
	UnitsPerEm             uint16
	PostScriptName         string
	Bold                   bool
	ItalicAngle            int16
	IsFixedPitch           bool
	TypoAscender           int16
	TypoDescender          int16
	UnderlinePosition      int16
	UnderlineThickness     int16
	Xmin, Ymin, Xmax, Ymax int16
	CapHeight              int16
	Widths                 []uint16
	Chars                  map[uint16]uint16
}

TtfType contains metrics of a TrueType font.

func TtfParse

func TtfParse(fileStr string) (TtfRec TtfType, err error)

TtfParse extracts various metrics from a TrueType font file.

Example
ttf, err := gofpdf.TtfParse(cnFontDir + "/calligra.ttf")
if err == nil {
	fmt.Printf("Postscript name:  %s\n", ttf.PostScriptName)
	fmt.Printf("unitsPerEm:       %8d\n", ttf.UnitsPerEm)
	fmt.Printf("Xmin:             %8d\n", ttf.Xmin)
	fmt.Printf("Ymin:             %8d\n", ttf.Ymin)
	fmt.Printf("Xmax:             %8d\n", ttf.Xmax)
	fmt.Printf("Ymax:             %8d\n", ttf.Ymax)
} else {
	fmt.Printf("%s\n", err)
}
Output:

Postscript name:  CalligrapherRegular
unitsPerEm:           1000
Xmin:                 -173
Ymin:                 -234
Xmax:                 1328
Ymax:                  899

Directories

Path Synopsis
Command makefont generates a font definition file.
Command makefont generates a font definition file.

Jump to

Keyboard shortcuts

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