canvas
| Language | Go |
|---|---|
| License | MIT |
| Repository | github.com/tdewolff/canvas |
| Documentation | pkg.go.dev/github.com/tdewolff/canvas, renderers/ps |
| Depends on | pure Go (optional cgo for some font shaping) |
| Read / write | no / yes (PostScript and EPS) |
canvas draws paths, text (with font embedding and shaping) and images on a canvas.Canvas, then writes it with a renderer: PNG, JPEG, SVG, PDF, TeX/PGF, PostScript or EPS. The renderers package picks the format from the file extension, so the same drawing code produces PostScript and PDF.
Units are millimeters and the origin is the bottom-left corner, as in PostScript. The PostScript renderer can’t express transparency: semi-transparent colors print as opaque. canvas has no tagged releases; go get takes the latest commit.
Installation#
go get github.com/tdewolff/canvas
Basic usage: draw and save as PostScript#
package main
import (
"log"
"github.com/tdewolff/canvas"
"github.com/tdewolff/canvas/renderers"
)
func main() {
c := canvas.New(210, 297) // A4 in millimeters
ctx := canvas.NewContext(c)
ctx.SetFillColor(canvas.Steelblue)
ctx.DrawPath(20, 200, canvas.Rectangle(120, 60))
ctx.SetFillColor(canvas.Transparent)
ctx.SetStrokeColor(canvas.Red)
ctx.SetStrokeWidth(2)
ctx.DrawPath(105, 100, canvas.Circle(40))
// the extension selects the renderer: .ps, .eps, .pdf, .svg, .png
if err := renderers.Write("out.ps", c); err != nil {
log.Fatal(err)
}
}
How to add text to a PostScript file#
Load a font family, make a face, and draw a text line:
family := canvas.NewFontFamily("sans")
if err := family.LoadSystemFont("DejaVu Sans", canvas.FontRegular); err != nil {
log.Fatal(err)
}
face := family.Face(14.0, canvas.Black, canvas.FontRegular, canvas.FontNormal) // size in points
ctx.DrawText(20, 280, canvas.NewTextLine(face, "Hello, PostScript", canvas.Left))
family.LoadFontFile("font.ttf", canvas.FontRegular) loads a font from a file instead.
How to write PostScript to an io.Writer#
Use the PostScript renderer directly:
import (
"os"
"github.com/tdewolff/canvas"
"github.com/tdewolff/canvas/renderers/ps"
)
f, err := os.Create("out.ps")
if err != nil {
log.Fatal(err)
}
defer f.Close()
r := ps.New(f, 210, 297, &ps.Options{Format: ps.PostScript}) // or ps.EncapsulatedPostScript
ctx := canvas.NewContext(r)
ctx.DrawPath(20, 20, canvas.Rectangle(50, 50))
if err := r.Close(); err != nil {
log.Fatal(err)
}
How to crop the page to the drawing#
c.Fit(margin) shrinks the canvas to the bounding box of what you drew plus a margin (in millimeters):
c.Fit(5)
if err := c.WriteFile("figure.eps", renderers.EPS()); err != nil {
log.Fatal(err)
}
Tips#
renderers.PS()andrenderers.EPS()return writers forc.WriteFile, likerenderers.PDF()andrenderers.PNG().- Keep colors opaque for PostScript output, or render a PDF instead.