canvas

package module
v0.0.0-...-07bc63f Latest Latest
Warning

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

Go to latest
Published: Apr 15, 2021 License: MIT Imports: 37 Imported by: 0

README

Canvas

API reference Go Report Card Coverage Status Donate

Canvas is a common vector drawing target that can output SVG, PDF, EPS, raster images (PNG, JPG, GIF, ...), HTML Canvas through WASM, and OpenGL. It has a wide range of path manipulation functionality such as flattening, stroking and dashing implemented. Additionally, it has a good text formatter and embeds fonts (TTF, OTF, WOFF, or WOFF2) or converts them to outlines. It can be considered a Cairo or node-canvas alternative in Go. See the example below in Fig. 1 and Fig. 2 for an overview of the functionality.

Preview

Figure 1: top-left you can see text being fitted into a box and their bounding box (orange-red), the spaces between the words on the first row are being stretched to fill the whole width. You can see all the possible styles and text decorations applied. Also note the typographic substitutions (the quotes) and ligature support (fi, ffi, ffl, ...). Below the text box, 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 ellipse support showcasing precise dashing, notably the length of e.g. the short dash is equal wherever it is (approximated through arc length parametrization) on the curve. It also shows support for alternating dash lengths, in this case (2.0, 4.0, 2.0) for dashes and for spaces. Note that the dashes themselves are elliptical arcs as well (thus exactly precise even if magnified greatly). In the bottom-right we see a closed polygon of four points being smoothed by cubic Béziers that are smooth along the whole path, and next to it on the left an open path. In the middle you can see a rasterized image painted.

Figure 2abc: Three examples of what is possible with this library, for example the plotting of graphs, maps and documents.

Live WASM HTML Canvas example

Terminology: a path is a sequence of drawing commands (MoveTo, LineTo, QuadTo, CubeTo, ArcTo, Close) that completely describe a path. QuadTo and CubeTo are quadratic and cubic Béziers respectively, ArcTo is an elliptical arc, and Close is a LineTo to the last MoveTo command and closes the path (sometimes this has a special meaning such as when stroking). A path can consist of several subpaths by having more than one MoveTo or Close command. A subpath consists of path segments which are defined by a command and some values or coordinates.

Flattening is the act of converting the QuadTo, CubeTo and ArcTo segments into LineTos so that all path segments are linear.

Getting Started

With modules enabled, add the following imports and run the project with go get

import (
    "github.com/tdewolff/canvas"
)

Examples

Preview: canvas preview (as shown above) showing most of the functionality and exporting as PNG, SVG, PDF and EPS. It shows image and text rendering as well as LaTeX support and path functionality.

Map: data is loaded from Open Street Map of the city centre of Amsterdam and rendered to a PNG.

Graph: a simple graph is being plotted using the CO2 data from the Mauna Loa observatory.

Text document: a simple text document is rendered to PNG.

HTML Canvas: using WASM, a HTML Canvas is used as target. Live demo.

TeX/PGF: using the PGF (TikZ) LaTeX package, the output can be directly included in the main TeX file.

OpenGL: rendering example to an OpenGL target (WIP).

go-chart: using the go-chart library a financial graph is plotted.

gonum/plot: using the gonum/plot library an example is plotted.

Articles

My own

Papers

Status

Targets

Feature Image SVG PDF EPS WASM Canvas OpenGL
Draw path fill yes yes yes yes yes no
Draw path stroke yes yes yes no yes no
Draw path dash yes yes yes no yes no
Embed fonts yes yes no no no
Draw text path yes yes path path path
Draw image yes yes yes no yes no
EvenOdd fill rule no yes yes no no no
  • EPS does not support transparency
  • PDF and EPS do not support line joins for last and first dash for closed dashed path
  • OpenGL proper tessellation is missing

Path

Command Flatten Stroke Length SplitAt
LineTo yes yes yes yes
QuadTo yes (CubeTo) yes (CubeTo) yes yes (GL5 + Chebyshev10)
CubeTo yes yes yes (GL5) yes (GL5 + Chebyshev10)
ArcTo yes yes yes (GL5) yes (GL5 + Chebyshev10)
  • Ellipse => Cubic Bézier: used by rasterizer and PDF targets (see Maisonobe paper)

NB: GL5 means a Gauss-Legendre n=5, which is an numerical approximation as there is no analytical solution. Chebyshev is a converging way to approximate a function by an n=10 degree polynomial. It uses the bisection method as well to determine the polynomial points.

Planning

Features that are planned to be implemented in the future, with important issues in bold. Also see the TODOs in the code.

General

  • Fix slowness in the rasterizer (text_example.go is slow! use rasterized cache for each glyph/path)
  • Use general span placement algorithm (like CSS flexbox) that replace the current Text placer, to allow for text, image, path elements (e.g. inline formulas, inline icons or emoticons, ...)
  • Use word breaking algorithm from Knuth & Plass, implemented in JS in typeset. Use letter stretching and shrinking, shrinking by using ligatures, space shrinking and stretching (depending if space is between words or after comma or dot), and spacing or shrinking between glyphs. Use a point system of how ugly breaks are on a paragraph basis. Also see Justify Just or Just Justify.
  • Load in Markdown/HTML formatting and turn into text
  • Add OpenGL target, needs tessellation (see Delaunay triangulation). See Resolution independent NURBS curves rendering using programmable graphics pipeline and poly2tri-go. Use rational quadratic Beziérs to represent quadratic Beziérs and elliptic arcs exactly, and reduce degree of cubic Beziérs. Using a fragment shader we can draw all curves exactly. Or use rational cubic Beziérs to represent them all exactly?

Fonts

  • Compressing fonts and embedding only used characters
  • Use ligature and OS/2 tables
  • Support EOT font format
  • Font embedding for EPS
  • Support font hinting (for the rasterizer)?

Paths

  • Avoid overlapping paths when offsetting in corners
  • Get position and derivative/normal at length L along the path
  • Simplify polygons using the Ramer-Douglas-Peucker algorithm
  • Intersection function between line, Bézier and ellipse and between themselves (for path merge, overlap/mask, clipping, etc.)
  • Implement Bentley-Ottmann algorithm to find all line intersections (clipping)

Far future

  • Support fill gradients and patterns (hard)
  • Load in PDF, SVG and EPS and turn to paths/text
  • Generate TeX-like formulas in pure Go, use OpenType math font such as STIX or TeX Gyre

Canvas

c := canvas.New(width, height float64)

ctx := canvas.NewContext(c)
ctx.Push()               // save state set by function below on the stack
ctx.Pop()                // pop state from the stack
ctx.SetView(Matrix)      // set view transformation, all drawn elements are transformed by this matrix
ctx.ComposeView(Matrix)  // add transformation after the current view transformation
ctx.ResetView()          // use identity transformation matrix
ctx.SetFillColor(color.Color)
ctx.SetStrokeColor(color.Color)
ctx.SetStrokeCapper(Capper)
ctx.SetStrokeJoiner(Joiner)
ctx.SetStrokeWidth(width float64)
ctx.SetDashes(offset float64, lengths ...float64)

ctx.DrawPath(x, y float64, *Path)
ctx.DrawText(x, y float64, *Text)
ctx.DrawImage(x, y float64, image.Image, dpm float64)

c.Fit(margin float64)  // resize canvas to fit all elements with a given margin

c.WriteFile(filename string, svg.Writer)
c.WriteFile(filename string, pdf.Writer)
c.WriteFile(filename string, eps.Writer)
c.WriteFile(filename string, rasterizer.PNGWriter(resolution DPMM))
c.WriteFile(filename string, rasterizer.JPGWriter(resolution DPMM, opts *jpeg.Options))
c.WriteFile(filename string, rasterizer.GIFWriter(resolution DPMM, opts *gif.Options))
rasterizer.Draw(c *Canvas, resolution DPMM) *image.RGBA

Canvas allows to draw either paths, text or images. All positions and sizes are given in millimeters.

Text

Text Example

dejaVuSerif := NewFontFamily("dejavu-serif")
err := dejaVuSerif.LoadFontFile("DejaVuSerif.ttf", canvas.FontRegular)  // TTF, OTF, WOFF, or WOFF2
ff := dejaVuSerif.Face(size float64, color.Color, FontStyle, FontVariant, ...FontDecorator)

text = NewTextLine(ff, "string\nsecond line", halign) // simple text line
text = NewTextBox(ff, "string", width, height, halign, valign, indent, lineStretch)  // split on word boundaries and specify text alignment

// rich text allowing different styles of text in one box
richText := NewRichText()  // allow different FontFaces in the same text block
richText.Add(ff, "string")
text = richText.ToText(width, height, halign, valign, indent, lineStretch)

ctx.DrawText(0.0, 0.0, text)

Note that the LoadLocalFont function will use fc-match "font name" to find the closest matching font.

Paths

A large deal of this library implements functionality for building paths. Any path can be constructed from a few basic commands, see below. Successive commands build up segments that start from the current pen position (which is the previous segments's end point) and are drawn towards a new end point. A path can consist of multiple subpaths which each start with a MoveTo command (there is an implicit MoveTo after each Close command), but be aware that overlapping paths can cancel each other depending on the FillRule.

p := &Path{}
p.MoveTo(x, y float64)                                            // new subpath starting at (x,y)
p.LineTo(x, y float64)                                            // straight line to (x,y)
p.QuadTo(cpx, cpy, x, y float64)                                  // a quadratic Bézier with control point (cpx,cpy) and end point (x,y)
p.CubeTo(cp1x, cp1y, cp2x, cp2y, x, y float64)                    // a cubic Bézier with control points (cp1x,cp1y), (cp2x,cp2y) and end point (x,y)
p.ArcTo(rx, ry, rot float64, largeArc, sweep bool, x, y float64)  // an arc of an ellipse with radii (rx,ry), rotated by rot (in degrees CCW), with flags largeArc and sweep (booleans, see https://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands)
p.Arc(rx, ry, rot float64, theta0, theta1 float64)                // an arc of an ellipse with radii (rx,ry), rotated by rot (in degrees CCW), beginning at angle theta0 and ending at angle theta1
p.Close()                                                         // close the path, essentially a LineTo to the last MoveTo location

p = Rectangle(w, h float64)
p = RoundedRectangle(w, h, r float64)
p = BeveledRectangle(w, h, r float64)
p = Circle(r float64)
p = Ellipse(rx, ry float64)
p = RegularPolygon(n int, r float64, up bool)
p = RegularStarPolygon(n, d int, r float64, up bool)
p = StarPolygon(n int, R, r float64, up bool)

We can extract information from these paths using:

p.Empty() bool                 // true if path contains no segments (ie. no commands other than MoveTo or Close)
p.Pos() (x, y float64)         // current pen position
p.StartPos() (x, y float64)    // position of last MoveTo
p.Coords() []Point             // start/end positions of all segments
p.CCW() bool                   // true if the path is (mostly) counter clockwise
p.Interior(x, y float64) bool  // true if (x,y) is in the interior of the path, ie. gets filled (depends on FillRule)
p.Filling() []bool             // for all subpaths, true if the subpath is filling (depends on FillRule)
p.Bounds() Rect                // bounding box of path
p.Length() float64             // length of path in millimeters

These paths can be manipulated and transformed with the following commands. Each will return a pointer to the path.

p = p.Copy()
p = p.Append(q *Path)                 // append path q to p and return a new path
p = p.Join(q *Path)                   // join path q to p and return a new path
p = p.Reverse()                       // reverse the direction of the path
ps = p.Split() []*Path                // split the subpaths, ie. at Close/MoveTo
ps = p.SplitAt(d ...float64) []*Path  // split the path at certain lengths d

p = p.Transform(Matrix)               // apply multiple transformations at once and return a new path
p = p.Translate(x, y float64)

p = p.Flatten()                                            // flatten Bézier and arc segments to straight lines
p = p.Offset(width float64)                                // offset the path outwards (width > 0) or inwards (width < 0), depends on FillRule
p = p.Stroke(width float64, capper Capper, joiner Joiner)  // create a stroke from a path of certain width, using capper and joiner for caps and joins
p = p.Dash(offset float64, d ...float64)                   // create dashed path with lengths d which are alternating the dash and the space, start at an offset into the given pattern (can be negative)

Polylines

Some operations on paths only work when it consists of linear segments only. We can either flatten an existing path or use the start/end coordinates of the segments to create a polyline.

polyline := PolylineFromPath(p)       // create by flattening p
polyline = PolylineFromPathCoords(p)  // create from the start/end coordinates of the segments of p

polyline.Smoothen()              // smoothen it by cubic Béziers
polyline.FillCount() int         // returns the fill count as dictated by the FillRule
polyline.Interior(x, y float64)  // returns true if (x,y) is in the interior of the polyline

Path stroke

Below is an illustration of the different types of Cappers and Joiners you can use when creating a stroke of a path:

Stroke example

LaTeX

To generate outlines generated by LaTeX, you need latex and dvisvgm installed on your system.

p, err := ParseLaTeX(`$y=\sin\(\frac{x}{180}\pi\)$`)
if err != nil {
    panic(err)
}

Where the provided string gets inserted into the following document template:

\documentclass{article}
\begin{document}
\thispagestyle{empty}
{{input}}
\end{document}

Examples

See https://github.com/tdewolff/canvas/tree/master/examples for a working examples.

License

Released under the MIT license.

Documentation

Index

Constants

View Source
const DPI = DPMM(1 / 25.4)

DPI is a shortcut for Dots-per-Inch for the resolution of raster images.

View Source
const MaxGlyphSpacing = 0.5

MaxGlyphSpacing is the maximum amount times the x-height of the font that glyphs can be spaced.

View Source
const MaxSentenceSpacing = 3.5

MaxSentenceSpacing is the maximum amount times the x-height of the font that sentence spaces can expand.

View Source
const MaxWordSpacing = 2.5

MaxWordSpacing is the maximum amount times the x-height of the font that word spaces can expand.

Variables

View Source
var (
	Aliceblue            = color.RGBA{0xf0, 0xf8, 0xff, 0xff} // rgb(240, 248, 255)
	Antiquewhite         = color.RGBA{0xfa, 0xeb, 0xd7, 0xff} // rgb(250, 235, 215)
	Aqua                 = color.RGBA{0x00, 0xff, 0xff, 0xff} // rgb(0, 255, 255)
	Aquamarine           = color.RGBA{0x7f, 0xff, 0xd4, 0xff} // rgb(127, 255, 212)
	Azure                = color.RGBA{0xf0, 0xff, 0xff, 0xff} // rgb(240, 255, 255)
	Beige                = color.RGBA{0xf5, 0xf5, 0xdc, 0xff} // rgb(245, 245, 220)
	Bisque               = color.RGBA{0xff, 0xe4, 0xc4, 0xff} // rgb(255, 228, 196)
	Black                = color.RGBA{0x00, 0x00, 0x00, 0xff} // rgb(0, 0, 0)
	Blanchedalmond       = color.RGBA{0xff, 0xeb, 0xcd, 0xff} // rgb(255, 235, 205)
	Blue                 = color.RGBA{0x00, 0x00, 0xff, 0xff} // rgb(0, 0, 255)
	Blueviolet           = color.RGBA{0x8a, 0x2b, 0xe2, 0xff} // rgb(138, 43, 226)
	Brown                = color.RGBA{0xa5, 0x2a, 0x2a, 0xff} // rgb(165, 42, 42)
	Burlywood            = color.RGBA{0xde, 0xb8, 0x87, 0xff} // rgb(222, 184, 135)
	Cadetblue            = color.RGBA{0x5f, 0x9e, 0xa0, 0xff} // rgb(95, 158, 160)
	Chartreuse           = color.RGBA{0x7f, 0xff, 0x00, 0xff} // rgb(127, 255, 0)
	Chocolate            = color.RGBA{0xd2, 0x69, 0x1e, 0xff} // rgb(210, 105, 30)
	Coral                = color.RGBA{0xff, 0x7f, 0x50, 0xff} // rgb(255, 127, 80)
	Cornflowerblue       = color.RGBA{0x64, 0x95, 0xed, 0xff} // rgb(100, 149, 237)
	Cornsilk             = color.RGBA{0xff, 0xf8, 0xdc, 0xff} // rgb(255, 248, 220)
	Crimson              = color.RGBA{0xdc, 0x14, 0x3c, 0xff} // rgb(220, 20, 60)
	Cyan                 = color.RGBA{0x00, 0xff, 0xff, 0xff} // rgb(0, 255, 255)
	Darkblue             = color.RGBA{0x00, 0x00, 0x8b, 0xff} // rgb(0, 0, 139)
	Darkcyan             = color.RGBA{0x00, 0x8b, 0x8b, 0xff} // rgb(0, 139, 139)
	Darkgoldenrod        = color.RGBA{0xb8, 0x86, 0x0b, 0xff} // rgb(184, 134, 11)
	Darkgray             = color.RGBA{0xa9, 0xa9, 0xa9, 0xff} // rgb(169, 169, 169)
	Darkgreen            = color.RGBA{0x00, 0x64, 0x00, 0xff} // rgb(0, 100, 0)
	Darkgrey             = color.RGBA{0xa9, 0xa9, 0xa9, 0xff} // rgb(169, 169, 169)
	Darkkhaki            = color.RGBA{0xbd, 0xb7, 0x6b, 0xff} // rgb(189, 183, 107)
	Darkmagenta          = color.RGBA{0x8b, 0x00, 0x8b, 0xff} // rgb(139, 0, 139)
	Darkolivegreen       = color.RGBA{0x55, 0x6b, 0x2f, 0xff} // rgb(85, 107, 47)
	Darkorange           = color.RGBA{0xff, 0x8c, 0x00, 0xff} // rgb(255, 140, 0)
	Darkorchid           = color.RGBA{0x99, 0x32, 0xcc, 0xff} // rgb(153, 50, 204)
	Darkred              = color.RGBA{0x8b, 0x00, 0x00, 0xff} // rgb(139, 0, 0)
	Darksalmon           = color.RGBA{0xe9, 0x96, 0x7a, 0xff} // rgb(233, 150, 122)
	Darkseagreen         = color.RGBA{0x8f, 0xbc, 0x8f, 0xff} // rgb(143, 188, 143)
	Darkslateblue        = color.RGBA{0x48, 0x3d, 0x8b, 0xff} // rgb(72, 61, 139)
	Darkslategray        = color.RGBA{0x2f, 0x4f, 0x4f, 0xff} // rgb(47, 79, 79)
	Darkslategrey        = color.RGBA{0x2f, 0x4f, 0x4f, 0xff} // rgb(47, 79, 79)
	Darkturquoise        = color.RGBA{0x00, 0xce, 0xd1, 0xff} // rgb(0, 206, 209)
	Darkviolet           = color.RGBA{0x94, 0x00, 0xd3, 0xff} // rgb(148, 0, 211)
	Deeppink             = color.RGBA{0xff, 0x14, 0x93, 0xff} // rgb(255, 20, 147)
	Deepskyblue          = color.RGBA{0x00, 0xbf, 0xff, 0xff} // rgb(0, 191, 255)
	Dimgray              = color.RGBA{0x69, 0x69, 0x69, 0xff} // rgb(105, 105, 105)
	Dimgrey              = color.RGBA{0x69, 0x69, 0x69, 0xff} // rgb(105, 105, 105)
	Dodgerblue           = color.RGBA{0x1e, 0x90, 0xff, 0xff} // rgb(30, 144, 255)
	Firebrick            = color.RGBA{0xb2, 0x22, 0x22, 0xff} // rgb(178, 34, 34)
	Floralwhite          = color.RGBA{0xff, 0xfa, 0xf0, 0xff} // rgb(255, 250, 240)
	Forestgreen          = color.RGBA{0x22, 0x8b, 0x22, 0xff} // rgb(34, 139, 34)
	Fuchsia              = color.RGBA{0xff, 0x00, 0xff, 0xff} // rgb(255, 0, 255)
	Gainsboro            = color.RGBA{0xdc, 0xdc, 0xdc, 0xff} // rgb(220, 220, 220)
	Ghostwhite           = color.RGBA{0xf8, 0xf8, 0xff, 0xff} // rgb(248, 248, 255)
	Gold                 = color.RGBA{0xff, 0xd7, 0x00, 0xff} // rgb(255, 215, 0)
	Goldenrod            = color.RGBA{0xda, 0xa5, 0x20, 0xff} // rgb(218, 165, 32)
	Gray                 = color.RGBA{0x80, 0x80, 0x80, 0xff} // rgb(128, 128, 128)
	Green                = color.RGBA{0x00, 0x80, 0x00, 0xff} // rgb(0, 128, 0)
	Greenyellow          = color.RGBA{0xad, 0xff, 0x2f, 0xff} // rgb(173, 255, 47)
	Grey                 = color.RGBA{0x80, 0x80, 0x80, 0xff} // rgb(128, 128, 128)
	Honeydew             = color.RGBA{0xf0, 0xff, 0xf0, 0xff} // rgb(240, 255, 240)
	Hotpink              = color.RGBA{0xff, 0x69, 0xb4, 0xff} // rgb(255, 105, 180)
	Indianred            = color.RGBA{0xcd, 0x5c, 0x5c, 0xff} // rgb(205, 92, 92)
	Indigo               = color.RGBA{0x4b, 0x00, 0x82, 0xff} // rgb(75, 0, 130)
	Ivory                = color.RGBA{0xff, 0xff, 0xf0, 0xff} // rgb(255, 255, 240)
	Khaki                = color.RGBA{0xf0, 0xe6, 0x8c, 0xff} // rgb(240, 230, 140)
	Lavender             = color.RGBA{0xe6, 0xe6, 0xfa, 0xff} // rgb(230, 230, 250)
	Lavenderblush        = color.RGBA{0xff, 0xf0, 0xf5, 0xff} // rgb(255, 240, 245)
	Lawngreen            = color.RGBA{0x7c, 0xfc, 0x00, 0xff} // rgb(124, 252, 0)
	Lemonchiffon         = color.RGBA{0xff, 0xfa, 0xcd, 0xff} // rgb(255, 250, 205)
	Lightblue            = color.RGBA{0xad, 0xd8, 0xe6, 0xff} // rgb(173, 216, 230)
	Lightcoral           = color.RGBA{0xf0, 0x80, 0x80, 0xff} // rgb(240, 128, 128)
	Lightcyan            = color.RGBA{0xe0, 0xff, 0xff, 0xff} // rgb(224, 255, 255)
	Lightgoldenrodyellow = color.RGBA{0xfa, 0xfa, 0xd2, 0xff} // rgb(250, 250, 210)
	Lightgray            = color.RGBA{0xd3, 0xd3, 0xd3, 0xff} // rgb(211, 211, 211)
	Lightgreen           = color.RGBA{0x90, 0xee, 0x90, 0xff} // rgb(144, 238, 144)
	Lightgrey            = color.RGBA{0xd3, 0xd3, 0xd3, 0xff} // rgb(211, 211, 211)
	Lightpink            = color.RGBA{0xff, 0xb6, 0xc1, 0xff} // rgb(255, 182, 193)
	Lightsalmon          = color.RGBA{0xff, 0xa0, 0x7a, 0xff} // rgb(255, 160, 122)
	Lightseagreen        = color.RGBA{0x20, 0xb2, 0xaa, 0xff} // rgb(32, 178, 170)
	Lightskyblue         = color.RGBA{0x87, 0xce, 0xfa, 0xff} // rgb(135, 206, 250)
	Lightslategray       = color.RGBA{0x77, 0x88, 0x99, 0xff} // rgb(119, 136, 153)
	Lightslategrey       = color.RGBA{0x77, 0x88, 0x99, 0xff} // rgb(119, 136, 153)
	Lightsteelblue       = color.RGBA{0xb0, 0xc4, 0xde, 0xff} // rgb(176, 196, 222)
	Lightyellow          = color.RGBA{0xff, 0xff, 0xe0, 0xff} // rgb(255, 255, 224)
	Lime                 = color.RGBA{0x00, 0xff, 0x00, 0xff} // rgb(0, 255, 0)
	Limegreen            = color.RGBA{0x32, 0xcd, 0x32, 0xff} // rgb(50, 205, 50)
	Linen                = color.RGBA{0xfa, 0xf0, 0xe6, 0xff} // rgb(250, 240, 230)
	Magenta              = color.RGBA{0xff, 0x00, 0xff, 0xff} // rgb(255, 0, 255)
	Maroon               = color.RGBA{0x80, 0x00, 0x00, 0xff} // rgb(128, 0, 0)
	Mediumaquamarine     = color.RGBA{0x66, 0xcd, 0xaa, 0xff} // rgb(102, 205, 170)
	Mediumblue           = color.RGBA{0x00, 0x00, 0xcd, 0xff} // rgb(0, 0, 205)
	Mediumorchid         = color.RGBA{0xba, 0x55, 0xd3, 0xff} // rgb(186, 85, 211)
	Mediumpurple         = color.RGBA{0x93, 0x70, 0xdb, 0xff} // rgb(147, 112, 219)
	Mediumseagreen       = color.RGBA{0x3c, 0xb3, 0x71, 0xff} // rgb(60, 179, 113)
	Mediumslateblue      = color.RGBA{0x7b, 0x68, 0xee, 0xff} // rgb(123, 104, 238)
	Mediumspringgreen    = color.RGBA{0x00, 0xfa, 0x9a, 0xff} // rgb(0, 250, 154)
	Mediumturquoise      = color.RGBA{0x48, 0xd1, 0xcc, 0xff} // rgb(72, 209, 204)
	Mediumvioletred      = color.RGBA{0xc7, 0x15, 0x85, 0xff} // rgb(199, 21, 133)
	Midnightblue         = color.RGBA{0x19, 0x19, 0x70, 0xff} // rgb(25, 25, 112)
	Mintcream            = color.RGBA{0xf5, 0xff, 0xfa, 0xff} // rgb(245, 255, 250)
	Mistyrose            = color.RGBA{0xff, 0xe4, 0xe1, 0xff} // rgb(255, 228, 225)
	Moccasin             = color.RGBA{0xff, 0xe4, 0xb5, 0xff} // rgb(255, 228, 181)
	Navajowhite          = color.RGBA{0xff, 0xde, 0xad, 0xff} // rgb(255, 222, 173)
	Navy                 = color.RGBA{0x00, 0x00, 0x80, 0xff} // rgb(0, 0, 128)
	Oldlace              = color.RGBA{0xfd, 0xf5, 0xe6, 0xff} // rgb(253, 245, 230)
	Olive                = color.RGBA{0x80, 0x80, 0x00, 0xff} // rgb(128, 128, 0)
	Olivedrab            = color.RGBA{0x6b, 0x8e, 0x23, 0xff} // rgb(107, 142, 35)
	Orange               = color.RGBA{0xff, 0xa5, 0x00, 0xff} // rgb(255, 165, 0)
	Orangered            = color.RGBA{0xff, 0x45, 0x00, 0xff} // rgb(255, 69, 0)
	Orchid               = color.RGBA{0xda, 0x70, 0xd6, 0xff} // rgb(218, 112, 214)
	Palegoldenrod        = color.RGBA{0xee, 0xe8, 0xaa, 0xff} // rgb(238, 232, 170)
	Palegreen            = color.RGBA{0x98, 0xfb, 0x98, 0xff} // rgb(152, 251, 152)
	Paleturquoise        = color.RGBA{0xaf, 0xee, 0xee, 0xff} // rgb(175, 238, 238)
	Palevioletred        = color.RGBA{0xdb, 0x70, 0x93, 0xff} // rgb(219, 112, 147)
	Papayawhip           = color.RGBA{0xff, 0xef, 0xd5, 0xff} // rgb(255, 239, 213)
	Peachpuff            = color.RGBA{0xff, 0xda, 0xb9, 0xff} // rgb(255, 218, 185)
	Peru                 = color.RGBA{0xcd, 0x85, 0x3f, 0xff} // rgb(205, 133, 63)
	Pink                 = color.RGBA{0xff, 0xc0, 0xcb, 0xff} // rgb(255, 192, 203)
	Plum                 = color.RGBA{0xdd, 0xa0, 0xdd, 0xff} // rgb(221, 160, 221)
	Powderblue           = color.RGBA{0xb0, 0xe0, 0xe6, 0xff} // rgb(176, 224, 230)
	Purple               = color.RGBA{0x80, 0x00, 0x80, 0xff} // rgb(128, 0, 128)
	Red                  = color.RGBA{0xff, 0x00, 0x00, 0xff} // rgb(255, 0, 0)
	Rosybrown            = color.RGBA{0xbc, 0x8f, 0x8f, 0xff} // rgb(188, 143, 143)
	Royalblue            = color.RGBA{0x41, 0x69, 0xe1, 0xff} // rgb(65, 105, 225)
	Saddlebrown          = color.RGBA{0x8b, 0x45, 0x13, 0xff} // rgb(139, 69, 19)
	Salmon               = color.RGBA{0xfa, 0x80, 0x72, 0xff} // rgb(250, 128, 114)
	Sandybrown           = color.RGBA{0xf4, 0xa4, 0x60, 0xff} // rgb(244, 164, 96)
	Seagreen             = color.RGBA{0x2e, 0x8b, 0x57, 0xff} // rgb(46, 139, 87)
	Seashell             = color.RGBA{0xff, 0xf5, 0xee, 0xff} // rgb(255, 245, 238)
	Sienna               = color.RGBA{0xa0, 0x52, 0x2d, 0xff} // rgb(160, 82, 45)
	Silver               = color.RGBA{0xc0, 0xc0, 0xc0, 0xff} // rgb(192, 192, 192)
	Skyblue              = color.RGBA{0x87, 0xce, 0xeb, 0xff} // rgb(135, 206, 235)
	Slateblue            = color.RGBA{0x6a, 0x5a, 0xcd, 0xff} // rgb(106, 90, 205)
	Slategray            = color.RGBA{0x70, 0x80, 0x90, 0xff} // rgb(112, 128, 144)
	Slategrey            = color.RGBA{0x70, 0x80, 0x90, 0xff} // rgb(112, 128, 144)
	Snow                 = color.RGBA{0xff, 0xfa, 0xfa, 0xff} // rgb(255, 250, 250)
	Springgreen          = color.RGBA{0x00, 0xff, 0x7f, 0xff} // rgb(0, 255, 127)
	Steelblue            = color.RGBA{0x46, 0x82, 0xb4, 0xff} // rgb(70, 130, 180)
	Tan                  = color.RGBA{0xd2, 0xb4, 0x8c, 0xff} // rgb(210, 180, 140)
	Teal                 = color.RGBA{0x00, 0x80, 0x80, 0xff} // rgb(0, 128, 128)
	Thistle              = color.RGBA{0xd8, 0xbf, 0xd8, 0xff} // rgb(216, 191, 216)
	Tomato               = color.RGBA{0xff, 0x63, 0x47, 0xff} // rgb(255, 99, 71)
	Turquoise            = color.RGBA{0x40, 0xe0, 0xd0, 0xff} // rgb(64, 224, 208)
	Violet               = color.RGBA{0xee, 0x82, 0xee, 0xff} // rgb(238, 130, 238)
	Wheat                = color.RGBA{0xf5, 0xde, 0xb3, 0xff} // rgb(245, 222, 179)
	White                = color.RGBA{0xff, 0xff, 0xff, 0xff} // rgb(255, 255, 255)
	Whitesmoke           = color.RGBA{0xf5, 0xf5, 0xf5, 0xff} // rgb(245, 245, 245)
	Yellow               = color.RGBA{0xff, 0xff, 0x00, 0xff} // rgb(255, 255, 0)
	Yellowgreen          = color.RGBA{0x9a, 0xcd, 0x32, 0xff} // rgb(154, 205, 50)
)

from https://golang.org/x/image/colornames

View Source
var DefaultStyle = Style{
	FillColor:    Black,
	StrokeColor:  Transparent,
	StrokeWidth:  1.0,
	StrokeCapper: ButtCap,
	StrokeJoiner: MiterJoin,
	DashOffset:   0.0,
	Dashes:       []float64{},
	FillRule:     NonZero,
}

DefaultStyle is the default style for paths. It fills the path with a black color.

View Source
var Epsilon = 1e-10

Epsilon is the smallest number below which we assume the value to be zero. This is to avoid numerical floating point issues.

View Source
var Identity = Matrix{
	{1.0, 0.0, 0.0},
	{0.0, 1.0, 0.0},
}

Identity is the identity affine transformation matrix, ie. transforms any point to itself.

View Source
var Precision = 8

Precision is the number of significant digits at which floating point value will be printed to output formats.

View Source
var Tolerance = 0.01

Tolerance is the maximum deviation from the original path in millimeters when e.g. flatting

View Source
var Transparent = color.RGBA{0x00, 0x00, 0x00, 0x00} // rgba(0, 0, 0, 0)

Transparent when used as a fill or stroke color will indicate that the fill or stroke will not be drawn.

Functions

func Equal

func Equal(a, b float64) bool

Equal returns true if a and b are Equal with tolerance Epsilon.

func NewGoChart

func NewGoChart(writer Writer) func(int, int) (chart.Renderer, error)

NewGoChart returns a new github.com/wcharczuk/go-chart renderer.

func NewGonumPlot

func NewGonumPlot(r Renderer) draw.Canvas

NewGonumPlot returns a new github.com/gonum/plot/vg renderer.

Types

type ArcsJoiner

type ArcsJoiner struct {
	GapJoiner Joiner
	Limit     float64
}

ArcsJoiner is an arcs joiner.

func (ArcsJoiner) Join

func (j ArcsJoiner) Join(rhs, lhs *Path, halfWidth float64, pivot, n0, n1 Point, r0, r1 float64)

Join adds a join to a right-hand-side and left-hand-side path, of width 2*halfWidth, around a pivot point with starting and ending normals of n0 and n1, and radius of curvatures of the previous and next segments.

func (ArcsJoiner) String

func (j ArcsJoiner) String() string

type BevelJoiner

type BevelJoiner struct{}

BevelJoiner is a bevel joiner.

func (BevelJoiner) Join

func (BevelJoiner) Join(rhs, lhs *Path, halfWidth float64, pivot, n0, n1 Point, r0, r1 float64)

Join adds a join to a right-hand-side and left-hand-side path, of width 2*halfWidth, around a pivot point with starting and ending normals of n0 and n1, and radius of curvatures of the previous and next segments.

func (BevelJoiner) String

func (BevelJoiner) String() string

type ButtCapper

type ButtCapper struct{}

ButtCapper is a butt capper.

func (ButtCapper) Cap

func (ButtCapper) Cap(p *Path, halfWidth float64, pivot, n0 Point)

Cap adds a cap to path p of width 2*halfWidth, at a pivot point and initial normal direction of n0.

func (ButtCapper) String

func (ButtCapper) String() string

type CSSColor

type CSSColor color.RGBA

CSSColor is a string formatter to convert a color.RGBA to a CSS color (hexadecimal or using rgba()).

func (CSSColor) String

func (color CSSColor) String() string

type Canvas

type Canvas struct {
	W, H float64
	// contains filtered or unexported fields
}

Canvas stores all drawing operations as layers that can be re-rendered to other renderers.

func New

func New(width, height float64) *Canvas

New returns a new Canvas that records all drawing operations into layers. The canvas can then be rendered to any other renderer.

func (*Canvas) Empty

func (c *Canvas) Empty() bool

Empty return true if the canvas is empty.

func (*Canvas) Fit

func (c *Canvas) Fit(margin float64)

Fit shrinks the canvas size so all elements fit. The elements are translated towards the origin when any left/bottom margins exist and the canvas size is decreased if any margins exist. It will maintain a given margin.

func (*Canvas) Render

func (c *Canvas) Render(r Renderer)

Render renders the accumulated canvas drawing operations to another renderer.

func (*Canvas) RenderImage

func (c *Canvas) RenderImage(img image.Image, m Matrix)

RenderImage renders an image to the canvas using a transformation matrix.

func (*Canvas) RenderPath

func (c *Canvas) RenderPath(path *Path, style Style, m Matrix)

RenderPath renders a path to the canvas using a style and a transformation matrix.

func (*Canvas) RenderText

func (c *Canvas) RenderText(text *Text, m Matrix)

RenderText renders a text object to the canvas using a transformation matrix.

func (*Canvas) Reset

func (c *Canvas) Reset()

Reset empties the canvas.

func (*Canvas) Size

func (c *Canvas) Size() (float64, float64)

Size returns the size of the canvas in mm.

func (*Canvas) WriteFile

func (c *Canvas) WriteFile(filename string, w Writer) error

WriteFile writes the canvas to a file named by filename using the given Writer (for the encoding).

type Capper

type Capper interface {
	Cap(*Path, float64, Point, Point)
}

Capper implements Cap, with rhs the path to append to, halfWidth the half width of the stroke, pivot the pivot point around which to construct a cap, and n0 the normal at the start of the path. The length of n0 is equal to the halfWidth.

var ButtCap Capper = ButtCapper{}

ButtCap caps the start or end of a path by a butt cap.

var RoundCap Capper = RoundCapper{}

RoundCap caps the start or end of a path by a round cap.

var SquareCap Capper = SquareCapper{}

SquareCap caps the start or end of a path by a square cap.

type Context

type Context struct {
	Renderer

	Style
	// contains filtered or unexported fields
}

Context maintains the state for the current path, path style, and view transformation matrix.

func NewContext

func NewContext(r Renderer) *Context

NewContext returns a new Context which is a wrapper around a Renderer. Context maintains state for the current path, path style, and view transformation matrix.

func (*Context) Arc

func (c *Context) Arc(rx, ry, rot, theta0, theta1 float64)

Arc adds an elliptical arc with radii rx and ry, with rot the counter clockwise rotation in degrees, and theta0 and theta1 the angles in degrees of the ellipse (before rot is applies) between which the arc will run. If theta0 < theta1, the arc will run in a CCW direction. If the difference between theta0 and theta1 is bigger than 360 degrees, one full circle will be drawn and the remaining part of diff % 360 (eg. a difference of 810 degrees will draw one full circle and an arc over 90 degrees).

func (*Context) ArcTo

func (c *Context) ArcTo(rx, ry, rot float64, large, sweep bool, x, y float64)

ArcTo adds an arc with radii rx and ry, with rot the counter clockwise rotation with respect to the coordinate system in degrees, large and sweep booleans (see https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths#Arcs), and x,y the end position of the pen. The start position of the pen was given by a previous command end point. When sweep is true it means following the arc in a CCW direction in the Cartesian coordinate system, ie. that is CW in the upper-left coordinate system as is the case in SVGs.

func (*Context) Close

func (c *Context) Close()

Close closes the current path.

func (*Context) ComposeView

func (c *Context) ComposeView(view Matrix)

ComposeView post-multiplies the current affine transformation matrix by the given one.

func (*Context) CubeTo

func (c *Context) CubeTo(cpx1, cpy1, cpx2, cpy2, x, y float64)

CubeTo adds a cubic Bézier path with control points cpx1,cpy1 and cpx2,cpy2 and end point x,y.

func (*Context) DrawImage

func (c *Context) DrawImage(x, y float64, img image.Image, dpm float64)

DrawImage draws an image at position (x,y), using an image encoding (Lossy or Lossless) and DPM (dots-per-millimeter). A higher DPM will draw a smaller image.

func (*Context) DrawPath

func (c *Context) DrawPath(x, y float64, paths ...*Path)

DrawPath draws a path at position (x,y) using the current draw state.

func (*Context) DrawText

func (c *Context) DrawText(x, y float64, texts ...*Text)

DrawText draws text at position (x,y) using the current draw state. In particular, it only uses the current affine transformation matrix.

func (*Context) Fill

func (c *Context) Fill()

Fill fills the current path and resets it.

func (*Context) FillStroke

func (c *Context) FillStroke()

FillStroke fills and then strokes the current path and resets it.

func (*Context) Height

func (c *Context) Height() float64

Height returns the height of the canvas.

func (*Context) LineTo

func (c *Context) LineTo(x, y float64)

LineTo adds a linear path to x,y.

func (*Context) MoveTo

func (c *Context) MoveTo(x, y float64)

MoveTo moves the path to x,y without connecting the path. It starts a new independent subpath. Multiple subpaths can be useful when negating parts of a previous path by overlapping it with a path in the opposite direction. The behaviour for overlapping paths depend on the FillRule.

func (*Context) Pop

func (c *Context) Pop()

Pop restores the last pushed draw state and uses that as the current draw state. If there are no states on the stack, this will do nothing.

func (*Context) Pos

func (c *Context) Pos() (float64, float64)

Pos returns the current position of the path, which is the end point of the last command.

func (*Context) Push

func (c *Context) Push()

Push saves the current draw state, so that it can be popped later on.

func (*Context) QuadTo

func (c *Context) QuadTo(cpx, cpy, x, y float64)

QuadTo adds a quadratic Bézier path with control point cpx,cpy and end point x,y.

func (*Context) ReflectX

func (c *Context) ReflectX()

ReflectX inverts the X axis of the view.

func (*Context) ReflectXAbout

func (c *Context) ReflectXAbout(x float64)

ReflectXAbout inverts the X axis of the view.

func (*Context) ReflectY

func (c *Context) ReflectY()

ReflectY inverts the Y axis of the view.

func (*Context) ReflectYAbout

func (c *Context) ReflectYAbout(y float64)

ReflectYAbout inverts the Y axis of the view.

func (*Context) ResetStyle

func (c *Context) ResetStyle()

ResetStyle resets the draw state to its default (colors, stroke widths, dashes, ...).

func (*Context) ResetView

func (c *Context) ResetView()

ResetView resets the current affine transformation matrix to the Identity matrix, ie. no transformations.

func (*Context) Rotate

func (c *Context) Rotate(rot float64)

Rotate rotates the view with rot in degrees.

func (*Context) RotateAbout

func (c *Context) RotateAbout(rot, x, y float64)

RotateAbout rotates the view around (x,y) with rot in degrees.

func (*Context) Scale

func (c *Context) Scale(sx, sy float64)

Scale scales the view.

func (*Context) ScaleAbout

func (c *Context) ScaleAbout(sx, sy, x, y float64)

ScaleAbout scales the view around (x,y).

func (*Context) SetCoordSystem

func (c *Context) SetCoordSystem(coordSystem CoordSystem)

SetCoordSystem sets the current affine transformation matrix through which all operation coordinates will be transformed as a Cartesian coordinate system.

func (*Context) SetCoordView

func (c *Context) SetCoordView(rect Rect, width, height float64)

SetCoordView sets the current affine transformation matrix through which all operation coordinates will be transformed.

func (*Context) SetDashes

func (c *Context) SetDashes(offset float64, dashes ...float64)

SetDashes sets the dash pattern to be used for stroking operations. The dash offset denotes the offset into the dash array in mm from where to start. Negative values are allowed.

func (*Context) SetFillColor

func (c *Context) SetFillColor(col color.Color)

SetFillColor sets the color to be used for filling operations.

func (*Context) SetFillRule

func (c *Context) SetFillRule(rule FillRule)

SetFillRule sets the fill rule to be used for filling paths.

func (*Context) SetStrokeCapper

func (c *Context) SetStrokeCapper(capper Capper)

SetStrokeCapper sets the line cap function to be used for stroke endpoints.

func (*Context) SetStrokeColor

func (c *Context) SetStrokeColor(col color.Color)

SetStrokeColor sets the color to be used for stroking operations.

func (*Context) SetStrokeJoiner

func (c *Context) SetStrokeJoiner(joiner Joiner)

SetStrokeJoiner sets the line join function to be used for stroke midpoints.

func (*Context) SetStrokeWidth

func (c *Context) SetStrokeWidth(width float64)

SetStrokeWidth sets the width in mm for stroking operations.

func (*Context) SetView

func (c *Context) SetView(view Matrix)

SetView sets the current affine transformation matrix through which all operations will be transformed.

func (*Context) Shear

func (c *Context) Shear(sx, sy float64)

Shear shear stretches the view.

func (*Context) ShearAbout

func (c *Context) ShearAbout(sx, sy, x, y float64)

ShearAbout shear stretches the view around (x,y).

func (*Context) Stroke

func (c *Context) Stroke()

Stroke strokes the current path and resets it.

func (*Context) Translate

func (c *Context) Translate(x, y float64)

Translate moves the view.

func (*Context) View

func (c *Context) View() Matrix

View returns the current affine transformation matrix.

func (*Context) Width

func (c *Context) Width() float64

Width returns the width of the canvas.

type CoordSystem

type CoordSystem int
const (
	CartesianI CoordSystem = iota
	CartesianII
	CartesianIII
	CartesianIV
)

type DPMM

type DPMM float64

DPMM (Dots-per-Millimetter) for the resolution of raster images. Higher DPMM will result in bigger images.

type FillRule

type FillRule int

FillRule is the algorithm to specify which area is to be filled and which not, in particular when multiple subpaths overlap. The NonZero rule is the default and will fill any point that is being enclosed by an unequal number of paths winding clockwise and counter clockwise, otherwise it will not be filled. The EvenOdd rule will fill any point that is being enclosed by an uneven number of path, whichever their direction.

const (
	NonZero FillRule = iota
	EvenOdd
)

see FillRule

type Font

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

Font defines a font of type TTF or OTF which which a FontFace can be generated for use in text drawing operations.

func (*Font) Bounds

func (f *Font) Bounds(ppem float64) Rect

Bounds returns the union of a Font's glyphs' bounds.

func (*Font) IndicesOf

func (f *Font) IndicesOf(s string) []uint16

func (*Font) ItalicAngle

func (f *Font) ItalicAngle() float64

ItalicAngle in counter-clockwise degrees from the vertical. Zero for upright text, negative for text that leans to the right (forward).

func (*Font) Kerning

func (f *Font) Kerning(left, right rune, ppem float64) (float64, error)

Kerning returns the horizontal adjustment for the rune pair. A positive kern means to move the glyphs further apart. Returns 0 if there is an error.

func (*Font) Metrics

func (f *Font) Metrics(ppem float64) FontMetrics

Metrics returns the font metrics.

func (*Font) Name

func (f *Font) Name() string

Name returns the name of the font.

func (*Font) Raw

func (f *Font) Raw() (string, []byte)

Raw returns the mimetype and raw binary data of the font.

func (*Font) UnitsPerEm

func (f *Font) UnitsPerEm() float64

UnitsPerEm returns the number of units per em for f.

func (*Font) Use

func (f *Font) Use(options TypographicOptions)

Use enables typographic options on the font such as ligatures.

func (*Font) Widths

func (f *Font) Widths(ppem float64) []float64

type FontDecorator

type FontDecorator interface {
	Decorate(FontFace, float64) *Path
}

FontDecorator is an interface that returns a path given a font face and a width in mm.

var FontDashedUnderline FontDecorator = dashedUnderline{}

FontDashedUnderline is a font decoration that draws a dashed line at the base line.

var FontDottedUnderline FontDecorator = dottedUnderline{}

FontDottedUnderline is a font decoration that draws a dotted line at the base line.

var FontDoubleUnderline FontDecorator = doubleUnderline{}

FontDoubleUnderline is a font decoration that draws two lines at the base line.

var FontOverline FontDecorator = overline{}

FontOverline is a font decoration that draws a line over the text at the X-Height line.

var FontSawtoothUnderline FontDecorator = sawtoothUnderline{}

FontSawtoothUnderline is a font decoration that draws a wavy sawtooth path at the base line.

var FontSineUnderline FontDecorator = sineUnderline{}

FontSineUnderline is a font decoration that draws a wavy sine path at the base line.

var FontStrikethrough FontDecorator = strikethrough{}

FontStrikethrough is a font decoration that draws a line through the text in the middle between the base and X-Height line.

var FontUnderline FontDecorator = underline{}

FontUnderline is a font decoration that draws a line under the text at the base line.

type FontFace

type FontFace struct {
	Font *Font

	Size    float64
	Style   FontStyle
	Variant FontVariant
	Color   color.RGBA

	Scale, Voffset, FauxBold, FauxItalic float64 // consequences of font style and variant
	// contains filtered or unexported fields
}

FontFace defines a font face from a given font. It allows setting the font size, its color, faux styles and font decorations.

func (FontFace) Boldness

func (ff FontFace) Boldness() int

func (FontFace) Decorate

func (ff FontFace) Decorate(width float64) *Path

Decorate will return a path from the decorations specified in the FontFace over a given width in mm.

func (FontFace) Equals

func (ff FontFace) Equals(other FontFace) bool

Equals returns true when two font face are equal. In particular this allows two adjacent text spans that use the same decoration to allow the decoration to span both elements instead of two separately.

func (FontFace) Kerning

func (ff FontFace) Kerning(rPrev, rNext rune) float64

Kerning returns the eventual kerning between two runes in mm (ie. the adjustment on the advance).

func (FontFace) Metrics

func (ff FontFace) Metrics() FontMetrics

Metrics returns the font metrics. See https://developer.apple.com/library/archive/documentation/TextFonts/Conceptual/CocoaTextArchitecture/Art/glyph_metrics_2x.png for an explanation of the different metrics.

func (FontFace) Name

func (ff FontFace) Name() string

Name returns the name of the underlying font

func (FontFace) TextWidth

func (ff FontFace) TextWidth(s string) float64

TextWidth returns the width of a given string in mm.

func (FontFace) ToPath

func (ff FontFace) ToPath(s string) (*Path, float64)

ToPath converts a string to a path and also returns its advance in mm.

type FontFamily

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

FontFamily contains a family of fonts (bold, italic, ...). Selecting an italic style will pick the native italic font or use faux italic if not present.

func NewFontFamily

func NewFontFamily(name string) *FontFamily

NewFontFamily returns a new FontFamily.

func (*FontFamily) Face

func (family *FontFamily) Face(size float64, col color.Color, style FontStyle, variant FontVariant, deco ...FontDecorator) FontFace

Face gets the font face given by the font size (in pt).

func (*FontFamily) LoadFont

func (family *FontFamily) LoadFont(b []byte, style FontStyle) error

LoadFont loads a font from memory.

func (*FontFamily) LoadFontFile

func (family *FontFamily) LoadFontFile(filename string, style FontStyle) error

LoadFontFile loads a font from a file.

func (*FontFamily) LoadLocalFont

func (family *FontFamily) LoadLocalFont(name string, style FontStyle) error

LoadLocalFont loads a font from the system fonts location.

func (*FontFamily) Use

func (family *FontFamily) Use(options TypographicOptions)

Use specifies which typographic options shall be used, ie. whether to use common typographic substitutions and which ligatures classes to use.

type FontMetrics

type FontMetrics struct {
	LineHeight float64
	Ascent     float64
	Descent    float64
	XHeight    float64
	CapHeight  float64
}

FontMetrics contains a number of metrics that define a font face. See https://developer.apple.com/library/archive/documentation/TextFonts/Conceptual/CocoaTextArchitecture/Art/glyph_metrics_2x.png for an explanation of the different metrics.

type FontStyle

type FontStyle int

FontStyle defines the font style to be used for the font.

const (
	FontRegular    FontStyle = 0 // 400
	FontItalic     FontStyle = 1
	FontExtraLight FontStyle = 2 << iota // 100
	FontLight                            // 200
	FontBook                             // 300
	FontMedium                           // 500
	FontSemibold                         // 600
	FontBold                             // 700
	FontBlack                            // 800
	FontExtraBlack                       // 900
)

see FontStyle

type FontVariant

type FontVariant int

FontVariant defines the font variant to be used for the font, such as subscript or smallcaps.

const (
	FontNormal FontVariant = 2 << iota
	FontSubscript
	FontSuperscript
	FontSmallcaps
)

see FontVariant

type GoChart

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

GoChart is a github.com/wcharczuk/go-chart renderer.

func (*GoChart) ArcTo

func (r *GoChart) ArcTo(cx, cy int, rx, ry, startAngle, delta float64)

ArcTo draws an arc with a given center (cx,cy) a given set of radii (rx,ry), a startAngle and delta (in radians).

func (*GoChart) Circle

func (r *GoChart) Circle(radius float64, x, y int)

Circle draws a circle at the given coords with a given radius.

func (*GoChart) ClearTextRotation

func (r *GoChart) ClearTextRotation()

ClearTextRotation clears rotation.

func (*GoChart) Close

func (r *GoChart) Close()

Close finalizes a shape as drawn by LineTo.

func (*GoChart) Fill

func (r *GoChart) Fill()

Fill fills the path, but does not stroke.

func (*GoChart) FillStroke

func (r *GoChart) FillStroke()

FillStroke fills and strokes a path.

func (*GoChart) GetDPI

func (r *GoChart) GetDPI() float64

GetDPI gets the DPI for the renderer.

func (*GoChart) LineTo

func (r *GoChart) LineTo(x, y int)

LineTo both starts a shape and draws a line to a given point from the previous point.

func (*GoChart) MeasureText

func (r *GoChart) MeasureText(body string) chart.Box

MeasureText measures text.

func (*GoChart) MoveTo

func (r *GoChart) MoveTo(x, y int)

MoveTo moves the cursor to a given point.

func (*GoChart) QuadCurveTo

func (r *GoChart) QuadCurveTo(cx, cy, x, y int)

QuadCurveTo draws a quad curve. cx and cy represent the bezier "control points".

func (*GoChart) ResetStyle

func (r *GoChart) ResetStyle()

ResetStyle should reset any style related settings on the renderer.

func (*GoChart) Save

func (r *GoChart) Save(w io.Writer) error

Save writes the image to the given writer.

func (*GoChart) SetClassName

func (r *GoChart) SetClassName(name string)

SetClassName sets the current class name.

func (*GoChart) SetDPI

func (r *GoChart) SetDPI(dpi float64)

SetDPI sets the DPI for the renderer.

func (*GoChart) SetFillColor

func (r *GoChart) SetFillColor(col drawing.Color)

SetFillColor sets the current fill color.

func (*GoChart) SetFont

func (r *GoChart) SetFont(font *truetype.Font)

SetFont sets a font for a text field.

func (*GoChart) SetFontColor

func (r *GoChart) SetFontColor(col drawing.Color)

SetFontColor sets a font's color

func (*GoChart) SetFontSize

func (r *GoChart) SetFontSize(size float64)

SetFontSize sets the font size for a text field.

func (*GoChart) SetStrokeColor

func (r *GoChart) SetStrokeColor(col drawing.Color)

SetStrokeColor sets the current stroke color.

func (*GoChart) SetStrokeDashArray

func (r *GoChart) SetStrokeDashArray(dashArray []float64)

SetStrokeDashArray sets the stroke dash array.

func (*GoChart) SetStrokeWidth

func (r *GoChart) SetStrokeWidth(width float64)

SetStrokeWidth sets the stroke width.

func (*GoChart) SetTextRotation

func (r *GoChart) SetTextRotation(radian float64)

SetTextRotation sets a rotation for drawing elements.

func (*GoChart) Stroke

func (r *GoChart) Stroke()

Stroke strokes the path.

func (*GoChart) Text

func (r *GoChart) Text(body string, x, y int)

Text draws a text blob.

type GonumPlot

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

GonumPlot is a github.com/gonum/plot/vg renderer.

func (*GonumPlot) DrawImage

func (r *GonumPlot) DrawImage(rect vg.Rectangle, img image.Image)

DrawImage draws the image, scaled to fit the destination rectangle.

func (*GonumPlot) Fill

func (r *GonumPlot) Fill(path vg.Path)

Fill fills the given path.

func (*GonumPlot) FillString

func (r *GonumPlot) FillString(f gonumFont.Face, pt vg.Point, text string)

FillString fills in text at the specified location using the given font. If the font size is zero, the text is not drawn.

func (*GonumPlot) Pop

func (r *GonumPlot) Pop()

Pop restores the context saved by the corresponding call to Push().

func (*GonumPlot) Push

func (r *GonumPlot) Push()

Push saves the current line width, the current dash pattern, the current transforms, and the current color onto a stack so that the state can later be restored by calling Pop().

func (*GonumPlot) Rotate

func (r *GonumPlot) Rotate(rad float64)

Rotate applies a rotation transform to the context. The parameter is specified in radians.

func (*GonumPlot) Scale

func (r *GonumPlot) Scale(x, y float64)

Scale applies a scaling transform to the context

func (*GonumPlot) SetColor

func (r *GonumPlot) SetColor(col color.Color)

SetColor sets the current drawing color. Note that fill color and stroke color are the same, so if you want different fill and stroke colors then you must set a color, draw fills, set a new color and then draw lines.

The initial color is black. If SetColor is called with a nil color then black is used.

func (*GonumPlot) SetLineDash

func (r *GonumPlot) SetLineDash(pattern []vg.Length, offset vg.Length)

SetLineDash sets the dash pattern for lines. The pattern slice specifies the lengths of alternating dashes and gaps, and the offset specifies the distance into the dash pattern to start the dash.

The initial dash pattern is a solid line.

func (*GonumPlot) SetLineWidth

func (r *GonumPlot) SetLineWidth(length vg.Length)

SetLineWidth sets the width of stroked paths. If the width is not positive then stroked lines are not drawn.

The initial line width is 1 point.

func (*GonumPlot) Size

func (r *GonumPlot) Size() (vg.Length, vg.Length)

Size returns the width and height of a Rectangle.

func (*GonumPlot) Stroke

func (r *GonumPlot) Stroke(path vg.Path)

Stroke strokes the given path.

func (*GonumPlot) Translate

func (r *GonumPlot) Translate(pt vg.Point)

Translate applies a translational transform to the context.

type Image

type Image struct {
	image.Image
	Bytes    []byte
	Mimetype string // image/png or image/jpeg for instance
}

Image allows the renderer to optimize specific cases

func NewJPEGImage

func NewJPEGImage(r io.Reader) (Image, error)

NewJPEGImage parses a reader to later give access to the JPEG raw bytes.

func NewPNGImage

func NewPNGImage(r io.Reader) (Image, error)

NewPNGImage parses a reader to later give access to the PNG raw bytes

type ImageEncoding

type ImageEncoding int

ImageEncoding defines whether the embedded image shall be embedded as Lossless (typically PNG) or Lossy (typically JPG).

const (
	Lossless ImageEncoding = iota
	Lossy
)

see ImageEncoding

type Joiner

type Joiner interface {
	Join(*Path, *Path, float64, Point, Point, Point, float64, float64)
}

Joiner implements Join, with rhs the right path and lhs the left path to append to, pivot the intersection of both path elements, n0 and n1 the normals at the start and end of the path respectively. The length of n0 and n1 are equal to the halfWidth.

var ArcsJoin Joiner = ArcsJoiner{BevelJoin, 10.0}

ArcsJoin connects two path elements by extending the ends of the paths as circle arcs until they meet. If this point is further than 10 mm * (strokeWidth / 2.0) away, this will result in a bevel join.

var BevelJoin Joiner = BevelJoiner{}

BevelJoin connects two path elements by a linear join.

var MiterJoin Joiner = MiterJoiner{BevelJoin, 2.0}

MiterJoin connects two path elements by extending the ends of the paths as lines until they meet. If this point is further than 2 mm * (strokeWidth / 2.0) away, this will result in a bevel join.

var RoundJoin Joiner = RoundJoiner{}

RoundJoin connects two path elements by a round join.

func ArcsClipJoin

func ArcsClipJoin(gapJoiner Joiner, limit float64) Joiner

ArcsClipJoin returns an ArcsJoiner with given limit in mm*strokeWidth/2.0 upon which the gapJoiner function will be used. Limit can be NaN so that the gapJoiner is never used.

func MiterClipJoin

func MiterClipJoin(gapJoiner Joiner, limit float64) Joiner

MiterClipJoin returns a MiterJoiner with given limit*strokeWidth/2.0 in mm upon which the gapJoiner function will be used. Limit can be NaN so that the gapJoiner is never used.

type Matrix

type Matrix [2][3]float64

Matrix is used for affine transformations. Be aware that concatenating transformation function will be evaluated right-to-left! So that Identity.Rotate(30).Translate(20,0) will first translate 20 points horizontally and then rotate 30 degrees counter clockwise.

func (Matrix) Decompose

func (m Matrix) Decompose() (float64, float64, float64, float64, float64, float64)

Decompose extracts the translation, rotation, scaling and rotation components (applied in the reverse order) as (tx, ty, theta, sx, sy, phi) with rotation counter clockwise. This corresponds to Identity.Translate(tx, ty).Rotate(theta).Scale(sx, sy).Rotate(phi).

func (Matrix) Det

func (m Matrix) Det() float64

Det returns the matrix determinant.

func (Matrix) Dot

func (m Matrix) Dot(p Point) Point

Dot returns the dot product between the matrix and the given vector (ie. apply transformation).

func (Matrix) Eigen

func (m Matrix) Eigen() (float64, float64, Point, Point)

Eigen returns the matrix eigenvalues and eigenvectors. The first eigenvalue is related to the first eigenvector, and so for the second pair. Eigenvectors are normalized.

func (Matrix) Equals

func (m Matrix) Equals(q Matrix) bool

Equals returns true if both matrices are equal with a tolerance of Epsilon.

func (Matrix) Inv

func (m Matrix) Inv() Matrix

Inv returns the matrix inverse.

func (Matrix) IsRigid

func (m Matrix) IsRigid() bool

IsRigid is true if the matrix consists of only (proper) rigid transformations, ie. no scaling or skew.

func (Matrix) IsTranslation

func (m Matrix) IsTranslation() bool

IsTranslation is true if the matrix consists of only translational components, ie. no rotation, scaling or skew.

func (Matrix) Mul

func (m Matrix) Mul(q Matrix) Matrix

Mul multiplies the current matrix by the given matrix (ie. combine transformations).

func (Matrix) Pos

func (m Matrix) Pos() (float64, float64)

Pos extracts the translation component as (tx, ty).

func (Matrix) ReflectX

func (m Matrix) ReflectX() Matrix

ReflectX adds a horizontal reflection transformation (ie. Scale(-1,1)).

func (Matrix) ReflectXAbout

func (m Matrix) ReflectXAbout(x float64) Matrix

ReflectXAbout adds a horizontal reflection transformation around position x.

func (Matrix) ReflectY

func (m Matrix) ReflectY() Matrix

ReflectY adds a vertical reflection transformation (ie. Scale(1,-1)).

func (Matrix) ReflectYAbout

func (m Matrix) ReflectYAbout(y float64) Matrix

ReflectYAbout adds a vertical reflection transformation around position y.

func (Matrix) Rotate

func (m Matrix) Rotate(rot float64) Matrix

Rotate adds a rotation transformation with rot in degree counter clockwise.

func (Matrix) RotateAbout

func (m Matrix) RotateAbout(rot, x, y float64) Matrix

RotateAbout adds a rotation transformation around point (x,y) with rot in degrees counter clockwise.

func (Matrix) Scale

func (m Matrix) Scale(sx, sy float64) Matrix

Scale adds a scaling transformation in sx and sy. When scale is negative it will flip those axes.

func (Matrix) ScaleAbout

func (m Matrix) ScaleAbout(sx, sy, x, y float64) Matrix

ScaleAbout adds a scaling transformation around point (x,y) in sx and sy. When scale is negative it will flip those axes.

func (Matrix) Shear

func (m Matrix) Shear(sx, sy float64) Matrix

Shear adds a shear transformation with sx the horizontal shear and sy the vertical shear.

func (Matrix) ShearAbout

func (m Matrix) ShearAbout(sx, sy, x, y float64) Matrix

ShearAbout adds a shear transformation around point (x,y) with sx the horizontal shear and sy the vertical shear.

func (Matrix) String

func (m Matrix) String() string

String returns a string representation of the affine transformation matrix as six values, where [a b c; d e f; g h i] will be written as "a b d e c f" as g, h and i have fixed values (0, 0 and 1 respectively).

func (Matrix) T

func (m Matrix) T() Matrix

T returns the matrix transpose.

func (Matrix) ToSVG

func (m Matrix) ToSVG(h float64) string

ToSVG writes out the matrix in SVG notation, taking care of the proper order of transformations.

func (Matrix) Translate

func (m Matrix) Translate(x, y float64) Matrix

Translate adds a translation in x and y.

type MiterJoiner

type MiterJoiner struct {
	GapJoiner Joiner
	Limit     float64
}

MiterJoiner is a miter joiner.

func (MiterJoiner) Join

func (j MiterJoiner) Join(rhs, lhs *Path, halfWidth float64, pivot, n0, n1 Point, r0, r1 float64)

Join adds a join to a right-hand-side and left-hand-side path, of width 2*halfWidth, around a pivot point with starting and ending normals of n0 and n1, and radius of curvatures of the previous and next segments.

func (MiterJoiner) String

func (j MiterJoiner) String() string

type Path

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

Path defines a vector path in 2D using a series of connected commands (MoveTo, LineTo, QuadTo, CubeTo, ArcTo and Close). Each command consists of a number of float64 values (depending on the command) that fully define the action. The first value is the command itself (as a float64). The last two values are the end point position of the pen after the action (x,y). QuadTo defined one control point (x,y) in between, CubeTo defines two control points, and ArcTo defines (rx,ry,phi,large+sweep) i.e. the radius in x and y, its rotation (in radians) and the large and sweep booleans in one float64. Only valid commands are appended, so that LineTo has a non-zero length, QuadTo's and CubeTo's control point(s) don't (both) overlap with the start and end point, and ArcTo has non-zero radii and has non-zero length. For ArcTo we also make sure the angle is is in the range [0, 2*PI) and we scale the radii up if they appear too small to fit the arc.

func BeveledRectangle

func BeveledRectangle(w, h, r float64) *Path

BeveledRectangle returns a rectangle with width w and height h with beveled corners at distance r from the corner.

func Circle

func Circle(r float64) *Path

Circle returns a circle with radius r.

func Ellipse

func Ellipse(rx, ry float64) *Path

Ellipse returns an ellipse with radii rx,ry.

func GlyphPath

func GlyphPath(sfnt *canvasFont.SFNT, glyphID uint16, size, x, y float64) (*Path, error)

func MustParseSVG

func MustParseSVG(s string) *Path

MustParseSVG parses an SVG path data string and panics if it fails.

func ParseLaTeX

func ParseLaTeX(s string, preamble ...string) (*Path, error)

ParseLaTeX parses a LaTeX formatted string into a path. It requires latex and dvisvgm to be installed on the machine. The content is surrounded by

\documentclass{article}
\begin{document}
\thispagestyle{empty}
{{input}}
\end{document}

func ParseSVG

func ParseSVG(s string) (*Path, error)

ParseSVG parses an SVG path data string.

func Rectangle

func Rectangle(w, h float64) *Path

Rectangle returns a rectangle with width w and height h.

func RegularPolygon

func RegularPolygon(n int, r float64, up bool) *Path

RegularPolygon returns a regular polygon with radius r and rotation rot in degrees. It uses n vertices/edges, so when n approaches infinity this will return a path that approximates a circle. n must be 3 or more. The up boolean defines whether the first point will point north or not.

func RegularStarPolygon

func RegularStarPolygon(n, d int, r float64, up bool) *Path

RegularStarPolygon returns a regular star polygon with radius r and rotation rot in degrees. It uses n vertices of density d. This will result in a self-intersection star in counter clockwise direction. If n/2 < d the star will be clockwise and if n and d are not coprime a regular polygon will be obtained, possible with multiple windings. n must be 3 or more and d 2 or more. The up boolean defines whether the first point will point north or not.

func RoundedRectangle

func RoundedRectangle(w, h, r float64) *Path

RoundedRectangle returns a rectangle with width w and height h with rounded corners of radius r. A negative radius will cast the corners inwards (ie. concave).

func StarPolygon

func StarPolygon(n int, R, r float64, up bool) *Path

StarPolygon returns a star polygon of n points with alternating radius R and r. The up boolean defines whether the first point (true) or second point (false) will be pointing north.

func StringPath

func StringPath(sfnt *canvasFont.SFNT, text string, size float64) (*Path, error)

func (*Path) Append

func (p *Path) Append(q *Path) *Path

Append appends path q to p and returns a new path if succesful (otherwise either p or q are returned).

func (*Path) Arc

func (p *Path) Arc(rx, ry, rot, theta0, theta1 float64) *Path

Arc adds an elliptical arc with radii rx and ry, with rot the counter clockwise rotation in degrees, and theta0 and theta1 the angles in degrees of the ellipse (before rot is applies) between which the arc will run. If theta0 < theta1, the arc will run in a CCW direction. If the difference between theta0 and theta1 is bigger than 360 degrees, one full circle will be drawn and the remaining part of diff % 360 (eg. a difference of 810 degrees will draw one full circle and an arc over 90 degrees).

func (*Path) ArcTo

func (p *Path) ArcTo(rx, ry, rot float64, large, sweep bool, x, y float64) *Path

ArcTo adds an arc with radii rx and ry, with rot the counter clockwise rotation with respect to the coordinate system in degrees, large and sweep booleans (see https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths#Arcs), and x,y the end position of the pen. The start position of the pen was given by a previous command end point. When sweep is true it means following the arc in a CCW direction in the Cartesian coordinate system, ie. that is CW in the upper-left coordinate system as is the case in SVGs.

func (*Path) Bounds

func (p *Path) Bounds() Rect

Bounds returns the bounding box rectangle of the path.

func (*Path) CCW

func (p *Path) CCW() bool

CCW returns true when the path has (mostly) a counter clockwise direction. Does not need the path to be closed and will return true for a empty or straight line.

func (*Path) Close

func (p *Path) Close() *Path

Close closes a (sub)path with a LineTo to the start of the path (the most recent MoveTo command). It also signals the path closes as opposed to being just a LineTo command, which can be significant for stroking purposes for example.

func (*Path) Closed

func (p *Path) Closed() bool

Closed returns true if the last subpath of p is a closed path.

func (*Path) Coords

func (p *Path) Coords() []Point

Coords returns all the coordinates of the segment start/end points.

func (*Path) Copy

func (p *Path) Copy() *Path

Copy returns a copy of p.

func (*Path) CubeTo

func (p *Path) CubeTo(cpx1, cpy1, cpx2, cpy2, x, y float64) *Path

CubeTo adds a cubic Bézier path with control points cpx1,cpy1 and cpx2,cpy2 and end point x,y.

func (*Path) Dash

func (p *Path) Dash(offset float64, d ...float64) *Path

Dash returns a new path that consists of dashes. The elements in d specify the width of the dashes and gaps. It will alternate between dashes and gaps when picking widths. If d is an array of odd length, it is equivalent of passing d twice in sequence. The offset specifies the offset used into d (or negative offset onto the path). Dash will be applied to each subpath independently.

func (*Path) Empty

func (p *Path) Empty() bool

Empty returns true if p is an empty path or consists of only MoveTos and Closes.

func (*Path) Equals

func (p *Path) Equals(q *Path) bool

Equals returns true if p and q are equal within tolerance Epsilon.

func (*Path) Filling

func (p *Path) Filling(fillRule FillRule) []bool

Filling returns whether each subpath gets filled or not. A path may not be filling when it negates another path and depends on the FillRule. If a subpath is not closed, it is implicitly assumed to be closed. If the path has no area it will return false.

func (*Path) Flatten

func (p *Path) Flatten() *Path

Flatten flattens all Bézier and arc curves into linear segments and returns a new path. It uses Tolerance as the maximum deviation.

func (*Path) Interior

func (p *Path) Interior(x, y float64, fillRule FillRule) bool

Interior is true when the point (x,y) is in the interior of the path, ie. gets filled. This depends on the FillRule.

func (*Path) Iterate

func (p *Path) Iterate(
	move func(Point, Point),
	line func(Point, Point),
	quad func(Point, Point, Point),
	cube func(Point, Point, Point, Point),
	arc func(Point, float64, float64, float64, bool, bool, Point),
	close func(Point, Point),
)

Iterate iterates oves the path commands and calls the respective functions move, line, quad, cube, arc, close when encountering a MoveTo, LineTo, QuadTo, CubeTo, ArcTo, Close command.

func (*Path) Join

func (p *Path) Join(q *Path) *Path

Join joins path q to p and returns a new path if succesful (otherwise either p or q are returned). Its like executing the commands in q to p in sequence, where if the first MoveTo of q doesn't coincide with p it will fallback to appending the paths.

func (*Path) Length

func (p *Path) Length() float64

Length returns the length of the path in millimeters. The length is approximated for cubic Béziers.

func (*Path) LineTo

func (p *Path) LineTo(x, y float64) *Path

LineTo adds a linear path to x,y.

func (*Path) Markers

func (p *Path) Markers(first, mid, last *Path, align bool) []*Path

Markers returns an array of start, mid and end markers along the path at the path coordinates between commands. Align will align the markers with the path direction so that the markers orient towards the path's left.

func (*Path) MoveTo

func (p *Path) MoveTo(x, y float64) *Path

MoveTo moves the path to x,y without connecting the path. It starts a new independent subpath. Multiple subpaths can be useful when negating parts of a previous path by overlapping it with a path in the opposite direction. The behaviour for overlapping paths depend on the FillRule.

func (*Path) Offset

func (p *Path) Offset(w float64, fillRule FillRule) *Path

Offset offsets the path to expand by w and returns a new path. If w is negative it will contract. Path must be closed.

func (*Path) Pos

func (p *Path) Pos() Point

Pos returns the current position of the path, which is the end point of the last command.

func (*Path) QuadTo

func (p *Path) QuadTo(cpx, cpy, x, y float64) *Path

QuadTo adds a quadratic Bézier path with control point cpx,cpy and end point x,y.

func (*Path) ReplaceArcs

func (p *Path) ReplaceArcs() *Path

ReplaceArcs replaces ArcTo commands by CubeTo commands.

func (*Path) Reverse

func (p *Path) Reverse() *Path

Reverse returns a new path that is the same path as p but in the reverse direction.

func (*Path) Split

func (p *Path) Split() []*Path

Split splits the path into its independent subpaths. The path is split before each MoveTo command. None of the subpaths shall be empty.

func (*Path) SplitAt

func (p *Path) SplitAt(ts ...float64) []*Path

SplitAt splits the path into separate paths at the specified intervals (given in millimeters) along the path.

func (*Path) StartPos

func (p *Path) StartPos() Point

StartPos returns the start point of the current subpath, ie. it returns the position of the last MoveTo command.

func (*Path) String

func (p *Path) String() string

String returns a string that represents the path similar to the SVG path data format (but not necessarily valid SVG).

func (*Path) Stroke

func (p *Path) Stroke(w float64, cr Capper, jr Joiner) *Path

Stroke converts a path into a stroke of width w and returns a new path. It uses cr to cap the start and end of the path, and jr to join all path elemtents. If the path closes itself, it will use a join between the start and end instead of capping them. The tolerance is the maximum deviation from the original path when flattening Béziers and optimizing the stroke.

func (*Path) Tessellate

func (p *Path) Tessellate() ([][3]Point, [][5]Point)

Tessellate tessellates the path and returns the triangles that fill the path. WIP

func (*Path) ToPDF

func (p *Path) ToPDF() string

ToPDF returns a string that represents the path in the PDF data format.

func (*Path) ToPS

func (p *Path) ToPS() string

ToPS returns a string that represents the path in the PostScript data format.

func (*Path) ToRasterizer

func (p *Path) ToRasterizer(ras *vector.Rasterizer, dpm float64)

ToRasterizer rasterizes the path using the given rasterizer with dpm the dots-per-millimeter.

func (*Path) ToSVG

func (p *Path) ToSVG() string

ToSVG returns a string that represents the path in the SVG path data format with minifications.

func (*Path) Transform

func (p *Path) Transform(m Matrix) *Path

Transform transform the path by the given transformation matrix and returns a new path.

func (*Path) Translate

func (p *Path) Translate(x, y float64) *Path

Translate translates the path by (x,y) and returns a new path.

type Point

type Point struct {
	X, Y float64
}

Point is a coordinate in 2D space. OP refers to the line that goes through the origin (0,0) and this point (x,y).

func (Point) Add

func (p Point) Add(q Point) Point

Add adds Q to P.

func (Point) Angle

func (p Point) Angle() float64

Angle returns the angle in radians between the x-axis and OP.

func (Point) AngleBetween

func (p Point) AngleBetween(q Point) float64

AngleBetween returns the angle between OP and OQ.

func (Point) Div

func (p Point) Div(f float64) Point

Div divides x and y by f.

func (Point) Dot

func (p Point) Dot(q Point) float64

Dot returns the dot product between OP and OQ, ie. zero if perpendicular and |OP|*|OQ| if aligned.

func (Point) Equals

func (p Point) Equals(q Point) bool

Equals returns true if P and Q are equal with tolerance Epsilon.

func (Point) Interpolate

func (p Point) Interpolate(q Point, t float64) Point

Interpolate returns a point on PQ that is linearly interpolated by t in [0,1], ie. t=0 returns P and t=1 returns Q.

func (Point) IsZero

func (p Point) IsZero() bool

IsZero returns true if P is exactly zero.

func (Point) Length

func (p Point) Length() float64

Length returns the length of OP.

func (Point) Mul

func (p Point) Mul(f float64) Point

Mul multiplies x and y by f.

func (Point) Neg

func (p Point) Neg() Point

Neg negates x and y.

func (Point) Norm

func (p Point) Norm(length float64) Point

Norm normalized OP to be of given length.

func (Point) PerpDot

func (p Point) PerpDot(q Point) float64

PerpDot returns the perp dot product between OP and OQ, ie. zero if aligned and |OP|*|OQ| if perpendicular.

func (Point) Rot

func (p Point) Rot(phi float64, p0 Point) Point

Rot rotates the line OP by phi radians CCW.

func (Point) Rot90CCW

func (p Point) Rot90CCW() Point

Rot90CCW rotates the line OP by 90 degrees CCW.

func (Point) Rot90CW

func (p Point) Rot90CW() Point

Rot90CW rotates the line OP by 90 degrees CW.

func (Point) Slope

func (p Point) Slope() float64

Slope returns the slope between OP, ie. y/x.

func (Point) String

func (p Point) String() string

String returns the string representation of a point, such as "(x,y)".

func (Point) Sub

func (p Point) Sub(q Point) Point

Sub subtracts Q from P.

type Polyline

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

Polyline defines a list of points in 2D space that form a polyline. If the last coordinate equals the first coordinate, we assume the polyline to close itself.

func PolylineFromPath

func PolylineFromPath(p *Path) *Polyline

PolylineFromPath returns a polyline from the given path by approximating it by linear line segments (ie. flattening).

func PolylineFromPathCoords

func PolylineFromPathCoords(p *Path) *Polyline

PolylineFromPathCoords returns a polyline from the given path from each of the start/end coordinates of the segments, ie. converting all non-linear segments to linear ones.

func (*Polyline) Add

func (p *Polyline) Add(x, y float64) *Polyline

Add adds a new point to the polyline.

func (*Polyline) Coords

func (p *Polyline) Coords() []Point

Coords returns the list of coordinates of the polyline.

func (*Polyline) FillCount

func (p *Polyline) FillCount(x, y float64) int

FillCount returns the number of times the test point is enclosed by the polyline. Counter clockwise enclosures are counted positively and clockwise enclosures negatively.

func (*Polyline) Interior

func (p *Polyline) Interior(x, y float64, fillRule FillRule) bool

Interior is true when the point (x,y) is in the interior of the path, ie. gets filled. This depends on the FillRule.

func (*Polyline) Smoothen

func (p *Polyline) Smoothen() *Path

Smoothen returns a new path that smoothens out a path using cubic Béziers between all the path points. It makes sure that the curvature is smooth along the whole path. If the path is closed, it will be smooth between start and end segment too.

func (*Polyline) ToPath

func (p *Polyline) ToPath() *Path

ToPath convertes the polyline to a path. If the last coordinate equals the first one, we close the path.

type Rect

type Rect struct {
	X, Y, W, H float64
}

Rect is a rectangle in 2D defined by a position and its width and height.

func (Rect) Add

func (r Rect) Add(q Rect) Rect

Add returns a rect that encompasses both the current rect and the given rect.

func (Rect) Equals

func (r Rect) Equals(q Rect) bool

Equals returns true if rectangles are equal with tolerance Epsilon.

func (Rect) Move

func (r Rect) Move(p Point) Rect

Move translates the rect.

func (Rect) String

func (r Rect) String() string

String returns a string representation of r such as "(xmin,ymin)-(xmax,ymax)".

func (Rect) ToPath

func (r Rect) ToPath() *Path

ToPath converts the rectangle to a *Path.

func (Rect) Transform

func (r Rect) Transform(m Matrix) Rect

Transform transforms the rectangle by affine transformation matrix m and returns the new bounds of that rectangle.

type Renderer

type Renderer interface {
	Size() (float64, float64)
	RenderPath(path *Path, style Style, m Matrix)
	RenderText(text *Text, m Matrix)
	RenderImage(img image.Image, m Matrix)
}

Renderer is an interface that renderers implement. It defines the size of the target (in mm) and functions to render paths, text objects and raster images.

type RichText

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

RichText allows to build up a rich text with text spans of different font faces and by fitting that into a box.

func NewRichText

func NewRichText() *RichText

NewRichText returns a new RichText.

func (*RichText) Add

func (rt *RichText) Add(ff FontFace, s string) *RichText

Add adds a new text span element.

func (*RichText) ToText

func (rt *RichText) ToText(width, height float64, halign, valign TextAlign, indent, lineStretch float64) *Text

ToText takes the added text spans and fits them within a given box of certain width and height.

type RoundCapper

type RoundCapper struct{}

RoundCapper is a round capper.

func (RoundCapper) Cap

func (RoundCapper) Cap(p *Path, halfWidth float64, pivot, n0 Point)

Cap adds a cap to path p of width 2*halfWidth, at a pivot point and initial normal direction of n0.

func (RoundCapper) String

func (RoundCapper) String() string

type RoundJoiner

type RoundJoiner struct{}

RoundJoiner is a round joiner.

func (RoundJoiner) Join

func (RoundJoiner) Join(rhs, lhs *Path, halfWidth float64, pivot, n0, n1 Point, r0, r1 float64)

Join adds a join to a right-hand-side and left-hand-side path, of width 2*halfWidth, around a pivot point with starting and ending normals of n0 and n1, and radius of curvatures of the previous and next segments.

func (RoundJoiner) String

func (RoundJoiner) String() string

type SquareCapper

type SquareCapper struct{}

SquareCapper is a square capper.

func (SquareCapper) Cap

func (SquareCapper) Cap(p *Path, halfWidth float64, pivot, n0 Point)

Cap adds a cap to path p of width 2*halfWidth, at a pivot point and initial normal direction of n0.

func (SquareCapper) String

func (SquareCapper) String() string

type Style

type Style struct {
	FillColor    color.RGBA
	StrokeColor  color.RGBA
	StrokeWidth  float64
	StrokeCapper Capper
	StrokeJoiner Joiner
	DashOffset   float64
	Dashes       []float64
	FillRule
}

Style is the path style that defines how to draw the path. When FillColor is transparent it will not fill the path. If StrokeColor is transparent or StrokeWidth is zero, it will not stroke the path. If Dashes is an empty array, it will not draw dashes but instead a solid stroke line. FillRule determines how to fill the path when paths overlap and have certain directions (clockwise, counter clockwise).

type Text

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

Text holds the representation of text using lines and text spans.

func NewTextBox

func NewTextBox(ff FontFace, s string, width, height float64, halign, valign TextAlign, indent, lineStretch float64) *Text

NewTextBox is an advanced text formatter that will calculate text placement based on the settings. It takes a font face, a string, the width or height of the box (can be zero for no limit), horizontal and vertical alignment (Left, Center, Right, Top, Bottom or Justify), text indentation for the first line and line stretch (percentage to stretch the line based on the line height).

func NewTextLine

func NewTextLine(ff FontFace, s string, halign TextAlign) *Text

NewTextLine is a simple text line using a font face, a string (supporting new lines) and horizontal alignment (Left, Center, Right).

func (*Text) Bounds

func (t *Text) Bounds() Rect

Bounds returns the bounding rectangle that defines the text box.

func (*Text) Empty

func (t *Text) Empty() bool

Empty is true if there are no text lines or no text spans.

func (*Text) Fonts

func (t *Text) Fonts() []*Font

Fonts returns list of fonts used.

func (*Text) Heights

func (t *Text) Heights() (float64, float64)

Height returns the height of the text using the font metrics, this is usually more than the bounds of the glyph outlines.

func (*Text) MostCommonFontFace

func (t *Text) MostCommonFontFace() FontFace

MostCommonFontFace returns the most common FontFace of the text

func (*Text) OutlineBounds

func (t *Text) OutlineBounds() Rect

OutlineBounds returns the rectangle that contains the entire text box, ie. the glyph outlines (slow).

func (*Text) RenderAsPath

func (t *Text) RenderAsPath(r Renderer, m Matrix)

RenderAsPath renders the text (and its decorations) converted to paths (calling r.RenderPath)

func (*Text) RenderDecoration

func (t *Text) RenderDecoration(r Renderer, m Matrix)

RenderDecoration renders the text decorations using the RenderPath method of the Renderer. TODO: check text decoration z-positions when text lines are overlapping https://github.com/tdewolff/canvas/pull/40#pullrequestreview-400951503 TODO: check compliance with https://drafts.csswg.org/css-text-decor-4/#text-line-constancy

func (*Text) WalkLines

func (t *Text) WalkLines(spanCallback func(y, dx float64, span TextSpan), renderDeco func(path *Path, style Style, m Matrix), m Matrix)

func (*Text) WalkSpans

func (t *Text) WalkSpans(cb func(y, dx float64, span TextSpan))

type TextAlign

type TextAlign int

TextAlign specifies how the text should align or whether it should be justified.

const (
	Left TextAlign = iota
	Right
	Center
	Top
	Bottom
	Justify
)

see TextAlign

type TextSpan

type TextSpan struct {
	Face FontFace
	Text string

	SentenceSpacing float64
	WordSpacing     float64
	GlyphSpacing    float64
	// contains filtered or unexported fields
}

func (TextSpan) Bounds

func (span TextSpan) Bounds(width float64) Rect

func (TextSpan) CountGlyphs

func (span TextSpan) CountGlyphs() int

CountGlyphs counts all the glyphs, where ligatures are separated into their constituent parts

func (TextSpan) ReplaceLigatures

func (span TextSpan) ReplaceLigatures() TextSpan

ReplaceLigatures replaces all ligatures by their constituent parts

func (TextSpan) Split

func (span TextSpan) Split(width float64) ([]TextSpan, bool)

func (TextSpan) ToPath

func (span TextSpan) ToPath(width float64) (*Path, *Path, color.RGBA)

TODO: transform to Draw to canvas and cache the glyph rasterizations? TODO: remove width argument and use span.width?

func (TextSpan) TrimLeft

func (span TextSpan) TrimLeft() TextSpan

func (TextSpan) TrimRight

func (span TextSpan) TrimRight() TextSpan

func (TextSpan) Words

func (span TextSpan) Words() []string

Words returns the text of the span, split on wordBoundaries

type TypographicOptions

type TypographicOptions int

TypographicOptions are the options that can be enabled to make typographic or ligature substitutions automatically.

const (
	NoTypography TypographicOptions = 2 << iota
	NoRequiredLigatures
	CommonLigatures
	DiscretionaryLigatures
	HistoricalLigatures
)

see TypographicOptions

type Writer

type Writer func(w io.Writer, c *Canvas) error

Writer can write a canvas to a writer

Directories

Path Synopsis
examples
html-canvas
Code generated for package main by go-bindata DO NOT EDIT.
Code generated for package main by go-bindata DO NOT EDIT.
map
tex

Jump to

Keyboard shortcuts

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