Canvas is a common vector drawing target that can output SVG, PDF, EPS, raster images (PNG, JPG, GIF, ...), HTML Canvas through WASM, OpenGL, and Gio. It has a wide range of path manipulation functionality such as flattening, stroking and dashing implemented. Additionally, it has a text formatter and embeds and subsets fonts (TTF, OTF, WOFF, WOFF2, or EOT) or converts them to outlines. It can be considered a Cairo or node-canvas alternative in Go. See the example below in Figure 1 for an overview of the functionality.
Figure 1: top-left you can see text being fitted into a box, justified using Donald Knuth's linea breaking algorithm to stretch the spaces between words to fill the whole width. You can observe a variety of styles and text decorations applied, as well as support for LTR/RTL mixing and complex scripts. In the bottom-right the word "stroke" is being stroked and drawn as a path. Top-right we see a LaTeX formula that has been converted to a path. Left of that we see an ellipse showcasing precise dashing, notably the length of e.g. the short dash is equal wherever it is on the curve. Note that the dashes themselves are elliptical arcs as well (thus exactly precise even if magnified greatly). To the right we see a closed polygon of four points being smoothed by cubic Béziers that are smooth along the whole path, and the blue line on the left shows a smoothed open path. On the bottom you can see a rotated rasterized image. The bottom-left shows path boolean operations. The result is equivalent for all renderers (PNG, PDF, SVG, etc.).
I'm actively looking for support in the form of donations or sponsorships to keep developing this library and highly appreciate any gesture. Please see the Sponsors button in GitHub for ways to contribute, or contact me directly.
Whether this library is ready for production environments is up to your own judgment. In general, this library is written thoughtfully and complete, but the scope of this work is so big and the implementation can be quite complex that inevitably it must have a great amount of bugs. Effort was put in writing unit and fuzz tests so that I suspect only special use-cases will stumble into bugs, but coverage is still lacking. As time permits, work is done to flesh-out functionality, find bugs, and optimize code. Optimization could be in execution time / reducing code complexity, reducing memory footprint, or reducing the length of paths from operation.
Execution performance is actually really good, especially the rasterizer is highly optimized with ASM. See for example a comparison of an extreme case in #280 (comment), where this library is at least twice as fast as existing solutions, and can handle bigger images than the likes of Inkscape and Cairo.
The path intersection code and path boolean operation code is quite complete and fast, and more importantly has a time complexity of O(n log n). It may suffer from numerical precision which can be avoided using Path.Gridsnap
beforehand.
Please issue bug reports or feature requests to help this library mature! All help is appreciated. Also see Wiki - Planning for an inexhaustive list of ideas and TODOs.
- Path segment types: MoveTo, LineTo, QuadTo, CubeTo, ArcTo, Close (https://github.com/tdewolff/canvas/wiki/Paths)
- Precise path flattening, stroking, and dashing for all segment type uing papers (see below)
- Smooth spline generation through points for open and closed paths
- Path boolean operations: AND, OR, XOR, NOT, Divide (https://github.com/tdewolff/canvas/wiki/Boolean-operations)
- LaTeX to path conversion (native Go and CGO implementations available)
- Font formats support (https://github.com/tdewolff/canvas/wiki/Fonts-&-Text)
-
- SFNT (such as TTF, OTF, WOFF, WOFF2, EOT) supporting TrueType, CFF, and CFF2 tables
- HarfBuzz for text shaping (native Go and CGO implementations available)
- FriBidi for text bidirectionality (native Go and CGO implementations available)
- Donald Knuth's line breaking algorithm for text layout
- sRGB compliance (use
SRGBColorSpace
, only available for rasterizer) - Font rendering with gamma correction of 1.43
- Rendering targets (https://github.com/tdewolff/canvas/wiki/Renderers)
-
- Raster images (PNG, GIF, JPEG, TIFF, BMP, WEBP)
-
-
- SVG and SVGZ
-
- PS and EPS
-
- HTMLCanvas
-
- OpenGL
- Rendering sources
-
- Canvas itself
Amsterdam city centre: the centre of Amsterdam is drawn from data loaded from the Open Street Map API.
Mauna-Loa CO2 concentration: using data from the Mauna-Loa observatory, carbon dioxide concentrations over time are drawn
Text document: an example of a text document using the PDF backend.
OpenGL: an example using the OpenGL backend.
Gio: an example using the Gio backend.
Fyne: an example using the Fyne backend.
TeX/PGF: an example showing the usage of the PGF (TikZ) LaTeX package as renderer in order to generated a PDF using LaTeX.
go-chart: an example using the go-chart library, plotting a financial graph.
gonum/plot: an example using the gonum/plot library.
HTMLCanvas: an example using the HTMLCanvas backend, see the live demo.
This is a non-exhaustive list of library users I've come across. PRs are welcome to extend the list!
- https://github.com/aldernero/gaul (generative art utility library)
- https://github.com/aldernero/sketchy (generative art framework)
- https://github.com/carbocation/genomisc (genomics tools)
- https://github.com/davidhampgonsalves/life-dashboard (show text and emoticons in Kindle)
- https://github.com/davidhampgonsalves/quickdraw (grid of Google Quick Draw Drawings)
- https://github.com/dotaspirit/dotaspirit (draw Dota match data: https://vk.com/rsltdtk)
- https://github.com/engelsjk/go-annular (generative art of annular rings)
- https://github.com/eukarya-inc/reearth-plateauview
- https://github.com/holedaemon/gopster (Topster port)
- https://github.com/html2any/layout (flex layout)
- https://github.com/iand/genster (family trees)
- https://github.com/jansorg/marketplace-stats (reports for JetBrains marketplace)
- https://github.com/kpym/marianne (French republic logo)
- https://github.com/mrmelon54/favicon (Favicon generator)
- https://github.com/namsor/go-qrcode (QR code encoder)
- https://github.com/octohelm/gio-compose (UI component solution for Gio)
- https://github.com/omniskop/vitrum (GUI framework)
- https://github.com/Pavel7004/GraphPlot (plot graphs)
- https://github.com/peteraba/roadmapper (tracking roadmaps: https://rdmp.app/)
- https://github.com/Preston-PLB/choRenderer (render chord charts in propresenter7)
- https://github.com/stv0g/vand (camper/van monitor and control)
- https://github.com/uncopied/chirograph (barcode security for art)
- https://github.com/uncopied/go-qrcode (QR code encoder)
- https://github.com/wisepythagoras/gis-utils (GIS utilities)
- https://supertxt.net/git/st-int.html (SuperTXT integrations)
- https://github.com/kenshaw/fv (Command-line font viewer using terminal graphics)
- Numerically stable quadratic formula
- Quadratic Bézier length
- Bézier spline through open path
- Bézier spline through closed path
- Point inclusion in polygon test
- M. Walter, A. Fournier, Approximate Arc Length Parametrization, Anais do IX SIBGRAPHI (1996), p. 143--150
- T.F. Hain, et al., Fast, precise flattening of cubic Bézier path and offset curves, Computers & Graphics 29 (2005). p. 656--666
- M. Goldapp, Approximation of circular arcs by cubic polynomials, Computer Aided Geometric Design 8 (1991), p. 227--238
- L. Maisonobe, Drawing and elliptical arc using polylines, quadratic or cubic Bézier curves (2003)
- S.H. Kim and Y.J. Ahn, An approximation of circular arcs by quartic Bezier curves, Computer-Aided Design 39 (2007, p. 490--493)
- D.E. Knuth and M.F. Plass, Breaking Paragraphs into Lines, Software: Practice and Experience 11 (1981), p. 1119--1184
- L. Subramaniam, Partition of a non-simple polygon into simple polygons, 2003
- A simple algorithm for Boolean operations on polygons
Released under the MIT license.
Be aware that Fribidi uses the LGPL license.