canvas

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Mar 26, 2024 License: MIT Imports: 24 Imported by: 0

README

Canvas

API reference User guide Go Report Card Coverage Status Donate

API documentation

User guide

Live HTMLCanvas demo

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.

Preview

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.).

Sponsors

Please see https://www.patreon.com/tdewolff for ways to contribute, otherwise please contact me directly!

State

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 https://github.com/tdewolff/canvas/issues/280#issuecomment-1995990038, where this library is at least twice as fast as existing solutions, and can handle bigger images than the likes of Inkscape and Cairo.

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.

Recent changes

  • Context view and coordinate view have been altered. View now doesn't affect the coordinate view/system. To achieve the same as before, replace ctx.SetView(m) by ctx.SetView(m); ctx.SetCoordView(m). The change makes coordinate systems more intuitive when using in combination with views, the given coordinate reflects the coordinate where it is drawn irrespective of the view.
  • Flatten(), Stroke(), and Offset() now require an additional tolerance variable, which used to be set by the Tolerance parameter with a default value of 0.01. To get the original behaviour, use Flatten(0.01), Stroke(width, capper, joiner, 0.01), and Offset(width, fillRule, 0.01).
  • Interior() is renamed to Fills()
  • ParseSVG and MustParseSVG are now ParseSVGPath and MustParseSVGPath to avoid confusion that it parses entire SVGs
  • Instead of MiterClipJoin(limit) use MiterClipJoiner{nil, limit} or MiterClipJoin to use the default limit of 4.0, same for ArcsClipJoin
  • Path.Segments has been deprecated, please use Path.Scanner
  • *LocalFont have been deprecated, please use *SystemFont
  • RichText.SetFaceSpan has been deprecated
  • RichText.Add has been deprecated, please use RichText.WriteFace
  • RichText.Add* have been deprecated, please use RichText.Write*
  • Path.Complex has been renamed as Path.HasSubpaths

Features

  • Path segment types: MoveTo, LineTo, QuadTo, CubeTo, ArcTo, Close
  • 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
  • LaTeX to path conversion (native Go and CGO implementations available)
  • Font formats support
    • 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
    • Raster images (PNG, GIF, JPEG, TIFF, BMP, WEBP)
    • PDF
    • SVG and SVGZ
    • PS and EPS
    • HTMLCanvas
    • OpenGL
  • Rendering sources
    • Canvas itself

Examples

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.

Users

This is a non-exhaustive list of library users I've come across. PRs are welcome to extend the list!

Articles

My own

Papers

License

Released under the MIT license.

Be aware that Fribidi uses the LGPL license.

Documentation

Index

Constants

View Source
const (
	MoveToCmd = 1.0 << iota //  1.0
	LineToCmd               //  2.0
	QuadToCmd               //  4.0
	CubeToCmd               //  8.0
	ArcToCmd                // 16.0
	CloseCmd                // 32.0
)

Command values as powers of 2 so that the float64 representation is exact

View Source
const DefaultResolution = Resolution(96.0 * inchPerMm)

DefaultResolution is the default resolution used for font PPEMs and is set to 96 DPI.

Variables

View Source
var (
	A0        = Size{841.0, 1189.0}
	A1        = Size{594.0, 841.0}
	A2        = Size{420.0, 594.0}
	A3        = Size{297.0, 420.0}
	A4        = Size{210.0, 297.0}
	A5        = Size{148.0, 210.0}
	A6        = Size{105.0, 148.0}
	A7        = Size{74.0, 105.0}
	A8        = Size{52.0, 74.0}
	B0        = Size{1000.0, 1414.0}
	B1        = Size{707.0, 1000.0}
	B2        = Size{500.0, 707.0}
	B3        = Size{353.0, 500.0}
	B4        = Size{250.0, 353.0}
	B5        = Size{176.0, 250.0}
	B6        = Size{125.0, 176.0}
	B7        = Size{88.0, 125.0}
	B8        = Size{62.0, 88.0}
	B9        = Size{44.0, 62.0}
	B10       = Size{31.0, 44.0}
	C2        = Size{648.0, 458.0}
	C3        = Size{458.0, 324.0}
	C4        = Size{324.0, 229.0}
	C5        = Size{229.0, 162.0}
	C6        = Size{162.0, 114.0}
	D0        = Size{1090.0, 771.0}
	SRA0      = Size{1280.0, 900.0}
	SRA1      = Size{900.0, 640.0}
	SRA2      = Size{640.0, 450.0}
	SRA3      = Size{450.0, 320.0}
	SRA4      = Size{320.0, 225.0}
	RA0       = Size{1220.0, 860.0}
	RA1       = Size{860.0, 610.0}
	RA2       = Size{610.0, 430.0}
	Letter    = Size{215.9, 279.4}
	Legal     = Size{215.9, 355.6}
	Ledger    = Size{279.4, 431.8}
	Tabloid   = Size{431.8, 279.4}
	Executive = Size{184.1, 266.7}
)

Predefined paper sizes.

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 and https://www.w3.org/TR/css-color-4/#color-keywords

View Source
var DefaultStyle = Style{
	Fill:         Paint{Color: Black},
	Stroke:       Paint{},
	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 and has no stroke.

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, i.e. transforms any point to itself.

View Source
var Origin = Point{0.0, 0.0}

Origin is the coordinate system's origin.

View Source
var PixelTolerance = 0.1

PixelTolerance is the maximum deviation of the rasterized path from the original for flattening purposed in pixels.

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. Used for flattening in the renderers, font decorations, and path intersections.

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 DrawPreviewWithAssets

func DrawPreviewWithAssets(ctx *Context, latin, arabic, devanagari, lenna []byte) error

DrawPreviewWithAssets draws the canvas's preview to a Context with assets preloaded.

func Equal

func Equal(a, b float64) bool

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

func FindSystemFont

func FindSystemFont(name string, style FontStyle) (string, bool)

FindSystemFont finds the path to a font from the system's fonts.

func Hex

func Hex(s string) color.RGBA

Hex parses a CSS hexadecimal color such as e.g. #ff0000 or F00.

func Interval

func Interval(f, lower, upper float64) bool

Interval returns true if f is in closed interval [lower-Epsilon,upper+Epsilon] where lower and upper can be interchanged.

func IntervalExclusive

func IntervalExclusive(f, lower, upper float64) bool

IntervalExclusive returns true if f is in open interval [lower+Epsilon,upper-Epsilon] where lower and upper can be interchanged.

func RGB

func RGB(r, g, b uint8) color.RGBA

RGB returns a color given by red, green, and blue ∈ [0,255].

func RGBA

func RGBA(r, g, b uint8, a float64) color.RGBA

RGBA returns a color given by red, green, and blue ∈ [0,255] (non alpha premultiplied) and alpha ∈ [0,1].

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, which are positive for CCW arcs.

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 with width and height in millimeters, that records all drawing operations into layers. The canvas can then be rendered to any other renderer.

func NewFromSize

func NewFromSize(size Size) *Canvas

NewFromSize returns a new canvas of given size in millimeters, that records all drawing operations into layers. The canvas can then be rendered to any other renderer.

func (*Canvas) Clip

func (c *Canvas) Clip(rect Rect)

Clip sets the canvas are to the given rectangle.

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 that so all elements fit with a given margin in millimeters.

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) RenderTo

func (c *Canvas) RenderTo(r Renderer)

RenderTo renders the accumulated canvas drawing operations to another renderer.

func (*Canvas) RenderViewTo

func (c *Canvas) RenderViewTo(r Renderer, view Matrix)

RenderViewTo transforms and renders the accumulated canvas drawing operations to another renderer.

func (*Canvas) Reset

func (c *Canvas) Reset()

Reset empties the canvas.

func (*Canvas) SetZIndex

func (c *Canvas) SetZIndex(zindex int)

SetZIndex sets the z-index.

func (*Canvas) Size

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

Size returns the size of the canvas in millimeters.

func (*Canvas) Transform

func (c *Canvas) Transform(m Matrix)

Transform transforms the canvas.

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.

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 ColorSpace

type ColorSpace interface {
	ToLinear(color.Color) color.RGBA
	FromLinear(color.Color) color.RGBA
}

ColorSpace defines the color space within the RGB color model. All colors passed to this library are assumed to be in the sRGB color space, which is a ubiquitous assumption in most software. This works great for most applications, but fails when blending semi-transparent layers. See an elaborate explanation at https://blog.johnnovak.net/2016/09/21/what-every-coder-should-know-about-gamma/, which goes into depth of the problems of using sRGB for blending and the need for gamma correction. In short, we need to transform the colors, which are in the sRGB color space, to the linear color space, perform blending, and then transform them back to the sRGB color space. Unfortunately, almost all software does blending the wrong way (all PDF renderers and browsers I've tested), so by default this library will do the same by using LinearColorSpace which does no conversion from sRGB to linear and back but blends directly in sRGB. Or in other words, it assumes that colors are given in the linear color space and that the output image is expected to be in the linear color space as well. For technical correctness we should really be using the SRGBColorSpace, which will convert from sRGB to linear space, do blending in linear space, and then go back to sRGB space.

var DefaultColorSpace ColorSpace = LinearColorSpace{}

DefaultColorSpace is set to LinearColorSpace to match other renderers.

type Context

type Context struct {
	Renderer

	ContextState
	// 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. Contexts maintain the state of 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 applied) 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, e.g. 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's end point.

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 matrix. This means that any draw action will first be transformed by the new view matrix (parameter) and then by the current view matrix (ie. `Context.View()`). `Context.ComposeView(Identity.ReflectX())` is the same as `Context.ReflectX()`.

func (*Context) CoordView

func (c *Context) CoordView() Matrix

CoordView returns the current affine transformation matrix through which all operation coordinates will be transformed.

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, resolution Resolution)

DrawImage draws an image at position (x,y) using the current draw state and the given resolution in pixels-per-millimeter. A higher resolution will draw a smaller image (ie. more image pixels per millimeter of document).

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, text *Text)

DrawText draws text at position (x,y) using the current draw state.

func (*Context) Fill

func (c *Context) Fill()

Fill fills the current path and resets the path.

func (*Context) FillStroke

func (c *Context) FillStroke()

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

func (*Context) FitImage

func (c *Context) FitImage(img image.Image, rect Rect, fit ImageFit)

FitImage fits an image to a rectangle using different fit strategies.

func (*Context) Height

func (c *Context) Height() float64

Height returns the height of the canvas in millimeters.

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 with the previous 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 of overlapping paths depends 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 about the given X coordinate.

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 about the given Y coordinate.

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 counter clockwise with rot in degrees.

func (*Context) RotateAbout

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

RotateAbout rotates the view counter clockwise 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) SetCoordRect

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

SetCoordRect sets the current affine transformation matrix through which all operation coordinates will be transformed. It will transform coordinates from (0,0)--(width,height) to the target `rect`.

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(coordView Matrix)

SetCoordView sets the current affine transformation matrix through which all operation coordinates will be transformed. See `Matrix` for how transformations work.

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 millimeters from where to start. Negative values are allowed.

func (*Context) SetFill

func (c *Context) SetFill(ifill interface{})

SetFill sets the color, gradient, or pattern to be used for filling operations.

func (*Context) SetFillColor

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

SetFillColor sets the color to be used for filling operations.

func (*Context) SetFillGradient

func (c *Context) SetFillGradient(gradient Gradient)

SetFillGradient sets the gradient to be used for filling operations.

func (*Context) SetFillPattern

func (c *Context) SetFillPattern(pattern Pattern)

SetFillPattern sets the pattern 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) SetStroke

func (c *Context) SetStroke(istroke interface{})

SetStroke sets the color, gradient, or pattern to be used for stroke operations.

func (*Context) SetStrokeCapper

func (c *Context) SetStrokeCapper(capper Capper)

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

func (*Context) SetStrokeColor

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

SetStrokeColor sets the color to be used for stroking operations.

func (*Context) SetStrokeGradient

func (c *Context) SetStrokeGradient(gradient Gradient)

SetStrokeGradient sets the gradients 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 mid points.

func (*Context) SetStrokePattern

func (c *Context) SetStrokePattern(pattern Pattern)

SetStrokePattern sets the pattern to be used for stroking operations.

func (*Context) SetStrokeWidth

func (c *Context) SetStrokeWidth(width float64)

SetStrokeWidth sets the width in millimeters 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. See `Matrix` for how transformations work.

func (*Context) SetZIndex

func (c *Context) SetZIndex(zindex int)

SetZIndex sets the z-index. This will call the renderer's `SetZIndex` function only if it exists (in this case only for `Canvas`).

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) Size

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

Size returns the width and height of the canvas in millimeters.

func (*Context) Stroke

func (c *Context) Stroke()

Stroke strokes the current path and resets the path.

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 through which all operations will be transformed.

func (*Context) Width

func (c *Context) Width() float64

Width returns the width of the canvas in millimeters.

type ContextState

type ContextState struct {
	Style
	// contains filtered or unexported fields
}

ContextState defines the state of the context, including fill or stroke style, view and coordinate view.

type CoordSystem

type CoordSystem int

CoordSystem is the coordinate system, which can be either of the four cartesian quadrants. Most useful are the I'th and IV'th quadrants. CartesianI is the default quadrant with the zero-point in the bottom-left (the default for mathematics). The CartesianII has its zero-point in the bottom-right, CartesianIII in the top-right, and CartesianIV in the top-left (often used as default for printing devices). See https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Quadrants_and_octants for an explanation.

const (
	CartesianI CoordSystem = iota
	CartesianII
	CartesianIII
	CartesianIV
)

See CoordSystem.

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 clock-wise and counter clock-wise, otherwise it will not be filled. The EvenOdd rule will fill any point that is being enclosed by an uneven number of paths, whichever their direction. Positive fills only counter clock-wise oriented paths, while Negative fills only clock-wise oriented paths.

const (
	NonZero FillRule = iota
	EvenOdd
	Positive
	Negative
)

see FillRule

func (FillRule) Fills

func (fillRule FillRule) Fills(windings int) bool

type Font

type Font struct {
	*font.SFNT
	// contains filtered or unexported fields
}

Font defines an SFNT font such as TTF or OTF.

func LoadFont

func LoadFont(b []byte, index int, style FontStyle) (*Font, error)

LoadFont loads a font from memory.

func LoadFontCollection

func LoadFontCollection(filename string, index int, style FontStyle) (*Font, error)

LoadFontCollection loads a font from a collection file and uses the font at the specified index.

func LoadFontFile

func LoadFontFile(filename string, style FontStyle) (*Font, error)

LoadFontFile loads a font from a file.

func LoadSystemFont

func LoadSystemFont(name string, style FontStyle) (*Font, error)

LoadSystemFont loads a font from the system's fonts.

func (*Font) Destroy

func (f *Font) Destroy()

Destroy should be called when using HarfBuzz to free the C resources.

func (*Font) Face

func (f *Font) Face(size float64, ifill interface{}, deco ...FontDecorator) *FontFace

Face gets the font face given by the font size in points and its style. Fill can be any of Paint, color.Color, or canvas.Pattern.

func (*Font) Name

func (f *Font) Name() string

Name returns the name of the font.

func (*Font) SetFeatures

func (f *Font) SetFeatures(features string)

SetFeatures sets the font features (not yet supported).

func (*Font) SetVariations

func (f *Font) SetVariations(variations string)

SetVariations sets the font variations (not yet supported).

func (*Font) Style

func (f *Font) Style() FontStyle

Style returns the style of the font.

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 millimeters.

var FontDashedUnderline FontDecorator = dashedUnderline{}

FontDashedUnderline is a font decoration that draws a dashed line under the text.

var FontDottedUnderline FontDecorator = dottedUnderline{}

FontDottedUnderline is a font decoration that draws a dotted line under the text.

var FontDoubleUnderline FontDecorator = doubleUnderline{}

FontDoubleUnderline is a font decoration that draws two lines under the text.

var FontOverline FontDecorator = overline{}

FontOverline is a font decoration that draws a line over the text.

var FontSawtoothUnderline FontDecorator = sawtoothUnderline{}

FontSawtoothUnderline is a font decoration that draws a wavy sawtooth path under the text.

var FontSineUnderline FontDecorator = sineUnderline{}

FontSineUnderline is a font decoration that draws a wavy sine path under the text.

var FontStrikethrough FontDecorator = strikethrough{}

FontStrikethrough is a font decoration that draws a line through the text.

var FontUnderline FontDecorator = underline{}

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

var FontWavyUnderline FontDecorator = wavyUnderline{}

FontWavyUnderline is a font decoration that draws a wavy path under the text.

type FontFace

type FontFace struct {
	Font *Font

	Size    float64 // in mm
	Style   FontStyle
	Variant FontVariant

	Fill    Paint
	Deco    []FontDecorator
	Hinting font.Hinting

	// faux styles for bold, italic, and sub- and superscript
	FauxBold, FauxItalic float64
	XOffset, YOffset     int32

	Language  string
	Script    text.Script
	Direction text.Direction // TODO: really needed here?

	LetterSpacing int32

	MmPerEm float64 // millimeters per EM unit!
}

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

func (*FontFace) Decorate

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

Decorate will return the decoration path over a given width in millimeters.

func (*FontFace) Equals

func (face *FontFace) Equals(other *FontFace) bool

Equals returns true when two font face are equal.

func (*FontFace) HasDecoration

func (face *FontFace) HasDecoration() bool

HasDecoration returns true if the font face has decorations enabled.

func (*FontFace) LineHeight

func (face *FontFace) LineHeight() float64

LineHeight returns the height (ascent+descent) of a line.

func (*FontFace) Metrics

func (face *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 (face *FontFace) Name() string

Name returns the name of the underlying font.

func (*FontFace) PPEM

func (face *FontFace) PPEM(resolution Resolution) uint16

PPEM returns the pixels-per-EM for a given resolution of the font face.

func (*FontFace) TextWidth

func (face *FontFace) TextWidth(s string) float64

TextWidth returns the width of a given string in millimeters.

func (*FontFace) ToPath

func (face *FontFace) ToPath(s string) (*Path, float64, error)

ToPath converts a string to its glyph paths.

type FontFamily

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

FontFamily contains a family of fonts (bold, italic, ...). Allowing to select an italic style as the native italic font or to use faux italic if not present.

func NewFontFamily

func NewFontFamily(name string) *FontFamily

NewFontFamily returns a new font family.

func (*FontFamily) Destroy

func (family *FontFamily) Destroy()

Destroy should be called when using HarfBuzz to free the C resources.

func (*FontFamily) Face

func (family *FontFamily) Face(size float64, args ...interface{}) *FontFace

Face gets the font face given by the font size in points. Other arguments that can be passed: Paint/Pattern/color.Color (=Black), FontStyle (=FontRegular), FontVariant (=FontNormal), multiple FontDecorator, and Hinting (=VerticalHinting).

func (*FontFamily) LoadFont

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

LoadFont loads a font from memory.

func (*FontFamily) LoadFontCollection

func (family *FontFamily) LoadFontCollection(filename string, index int, style FontStyle) error

LoadFontCollection loads a font from a collection file and uses the font at the specified index.

func (*FontFamily) LoadFontFile

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

LoadFontFile loads a font from a file.

func (*FontFamily) LoadSystemFont

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

LoadSystemFont loads a font from the system's fonts.

func (*FontFamily) MustLoadFont

func (family *FontFamily) MustLoadFont(b []byte, index int, style FontStyle)

MustLoadFont loads a font from memory. It panics on error.

func (*FontFamily) MustLoadFontCollection

func (family *FontFamily) MustLoadFontCollection(filename string, index int, style FontStyle)

MustLoadFontCollection loads a font from a collection file and uses the font at the specified index. It panics on error.

func (*FontFamily) MustLoadFontFile

func (family *FontFamily) MustLoadFontFile(filename string, style FontStyle)

MustLoadFontFile loads a font from a filea and panics on error.

func (*FontFamily) MustLoadSystemFont

func (family *FontFamily) MustLoadSystemFont(name string, style FontStyle)

MustLoadSystemFont loads a font from the system's fonts and panics on error.

func (*FontFamily) Name

func (family *FontFamily) Name() string

Name returns the name of the font family.

func (*FontFamily) SetFeatures

func (family *FontFamily) SetFeatures(features string)

SetFeatures sets the font features (not yet supported).

func (*FontFamily) SetVariations

func (family *FontFamily) SetVariations(variations string)

SetVariations sets the font variations (not yet supported).

type FontMetrics

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

	XMin, YMin float64
	XMax, YMax 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.

func (FontMetrics) String

func (m FontMetrics) String() string

type FontStyle

type FontStyle int

FontStyle defines the font style to be used for the font. It specifies a boldness with optionally italic, e.g. FontBlack | FontItalic will specify a black boldness (a font-weight of 800 in CSS) and italic.

const (
	FontRegular    FontStyle = iota // 400
	FontThin                        // 100
	FontExtraLight                  // 200
	FontLight                       // 300
	FontMedium                      // 500
	FontSemiBold                    // 600
	FontBold                        // 700
	FontExtraBold                   // 800
	FontBlack                       // 900
	FontItalic     FontStyle = 1 << 8
)

see FontStyle

func (FontStyle) CSS

func (style FontStyle) CSS() int

CSS returns the CSS boldness value for the font face.

func (FontStyle) FauxWeight

func (style FontStyle) FauxWeight() float64

FauxWeight returns the path offset for fake boldness relative to regular style. The offset is multiplied by the font size (in millimeters) for an offset in millimeters.

func (FontStyle) Italic

func (style FontStyle) Italic() bool

Italic returns true if italic.

func (FontStyle) String

func (style FontStyle) String() string

func (FontStyle) Weight

func (style FontStyle) Weight() FontStyle

Weight returns the font weight (FontRegular, FontBold, ...)

type FontSubsetter

type FontSubsetter struct {
	IDs   []uint16          // old glyphIDs for increasing new glyphIDs
	IDMap map[uint16]uint16 // old to new glyphID
}

FontSubsetter holds a map between original glyph IDs and new glyph IDs in a subsetted font.

func NewFontSubsetter

func NewFontSubsetter() *FontSubsetter

NewFontSubsetter returns a new font subsetter.

func (*FontSubsetter) Get

func (subsetter *FontSubsetter) Get(glyphID uint16) uint16

Get maps a glyphID of the original font to the subsetted font. If the glyphID is not subsetted, it will be added to the map.

func (*FontSubsetter) List

func (subsetter *FontSubsetter) List() []uint16

List returns all subsetted IDs in the order of appearance.

type FontVariant

type FontVariant int

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

const (
	FontNormal FontVariant = iota
	FontSubscript
	FontSuperscript
	FontSmallcaps
)

see FontVariant

func (FontVariant) String

func (variant FontVariant) String() string

type GammaColorSpace

type GammaColorSpace struct {
	Gamma float64
}

GammaColorSpace assumes that input colors and output images are gamma-corrected with the given gamma value. The sRGB space uses a gamma=2.4 for most of the curve, but will on average have a gamma=2.2 best approximating the sRGB curve. See https://en.wikipedia.org/wiki/SRGB#The_sRGB_transfer_function_(%22gamma%22). According to https://www.puredevsoftware.com/blog/2019/01/22/sub-pixel-gamma-correct-font-rendering/, a gamma=1.43 is recommended for fonts.

func (GammaColorSpace) FromLinear

func (cs GammaColorSpace) FromLinear(col color.Color) color.RGBA

FromLinear decodes color from color space.

func (GammaColorSpace) ToLinear

func (cs GammaColorSpace) ToLinear(col color.Color) color.RGBA

ToLinear encodes color to color space.

type Gradient

type Gradient interface {
	SetView(Matrix) Gradient
	SetColorSpace(ColorSpace) Gradient
	At(float64, float64) color.RGBA
}

Gradient is a gradient pattern for filling.

type HatchPattern

type HatchPattern struct {
	Fill      Paint
	Thickness float64
	// contains filtered or unexported fields
}

Hatch pattern is a filling hatch pattern.

func NewCrossHatch

func NewCrossHatch(ifill interface{}, angle0, angle1, distance0, distance1, thickness float64) *HatchPattern

NewCrossHatch returns a new cross hatch pattern of two regular line hatches at different angles and with different distance intervals. Thickness is the stroke thickness applied to the shape; stroking is ignored with thickness is zero.

func NewHatchPattern

func NewHatchPattern(ifill interface{}, thickness float64, cell Matrix, hatch Hatcher) *HatchPattern

NewHatchPattern returns a new hatch pattern.

func NewLineHatch

func NewLineHatch(ifill interface{}, angle, distance, thickness float64) *HatchPattern

NewLineHatch returns a new line hatch pattern with lines at an angle with a spacing of distance. Thickness is the stroke thickness applied to the shape; stroking is ignored with thickness is zero.

func NewShapeHatch

func NewShapeHatch(ifill interface{}, shape *Path, distance, thickness float64) *HatchPattern

NewShapeHatch returns a new shape hatch that repeats the given shape over a rhombus primitive cell with sides of length distance. Thickness is the stroke thickness applied to the shape; stroking is ignored with thickness is zero.

func (*HatchPattern) ClipTo

func (p *HatchPattern) ClipTo(r Renderer, clip *Path)

ClipTo tiles the hatch pattern to the clipping path and renders it to the renderer.

func (*HatchPattern) SetColorSpace

func (p *HatchPattern) SetColorSpace(colorSpace ColorSpace) Pattern

SetColorSpace sets the color space. Automatically called by the rasterizer.

func (*HatchPattern) SetView

func (p *HatchPattern) SetView(view Matrix) Pattern

SetView sets the view. Automatically called by Canvas for coordinate system transformations.

func (*HatchPattern) Tile

func (p *HatchPattern) Tile(clip *Path) *Path

Tile tiles the hatch pattern within the clipping path.

type Hatcher

type Hatcher func(float64, float64, float64, float64) *Path

Hatcher is a hatch pattern along the cell's axes. The rectangle (x0,y0)-(x1,y1) is expressed in the unit cell's coordinate system, and the returned path should be transformed by the cell to obtain the final hatch pattern.

type Image

type Image struct {
	image.Image
	Mimetype string
	Bytes    []byte
}

Image is a raster image. Keeping the original bytes allows the renderer to optimize rendering in some cases.

func NewJPEGImage

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

NewJPEGImage parses a JPEG image.

func NewPNGImage

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

NewPNGImage parses a PNG image

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 ImageFit

type ImageFit int

ImageFit specifies how an image should fit a rectangle. ImageFill completely fills a rectangle by stretching the image. ImageContain and ImageCover both keep the aspect ratio of an image, where ImageContain scales the image such that it is complete contained in the rectangle (but possibly not completely covered), while ImageCover scales the image such that is completely covers the rectangle (but possibly extends beyond the boundaries of the rectangle).

const (
	ImageFill ImageFit = iota
	ImageContain
	ImageCover
)

See ImageFit.

type Intersection

type Intersection struct {
	Point              // coordinate of intersection
	T       [2]float64 // position along segment [0,1]
	Dir     [2]float64 // direction at intersection [0,2*pi)
	Tangent bool       // intersection is tangent (touches) instead of secant (crosses)
}

Intersection is an intersection between two path segments, e.g. Line x Line. Note that intersection is tangent also when it is one of the endpoints, in which case it may be tangent for this segment but we should double check when converting to a PathIntersection as it may or may not cross depending on the adjacent segment(s). Also, the Into value at tangent intersections at endpoints should be interpreted as if the paths were extended and the path would go into the left-hand side of the other path. Possible types of intersections:

  • Crossing not at endpoint: Tangent=false, Aligned=false
  • Touching not at endpoint: Tangent=true, Aligned=true, Into is invalid
  • Touching at endpoint: Tangent=true, may be aligned for (partly) overlapping paths

NB: for quad/cube/ellipse aligned angles at the endpoint for non-overlapping curves are deviated slightly to correctly calculate the value for Into, and will thus not be aligned

func (Intersection) Aligned

func (z Intersection) Aligned() bool

Aligned is true when both paths are aligned at the intersection (angles are equal).

func (Intersection) AntiAligned

func (z Intersection) AntiAligned() bool

AntiAligned is true when both paths are anti-aligned at the intersection (angles are opposite).

func (Intersection) Equals

func (z Intersection) Equals(o Intersection) bool

func (Intersection) Into

func (z Intersection) Into() bool

Into returns true if first path goes into the left-hand side of the second path, i.e. the second path goes to the right-hand side of the first path.

func (Intersection) String

func (z Intersection) String() string

type Intersections

type Intersections []Intersection

func (Intersections) Has

func (zs Intersections) Has() bool

Has returns true if there are secant/tangent intersections.

func (Intersections) HasSecant

func (zs Intersections) HasSecant() bool

HasSecant returns true when there are secant intersections, i.e. the curves intersect and cross (they cut).

func (Intersections) HasTangent

func (zs Intersections) HasTangent() bool

HasTangent returns true when there are tangent intersections, i.e. the curves intersect but don't cross (they touch).

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 ArcsClipJoin Joiner = ArcsJoiner{nil, 4.0}
var ArcsJoin Joiner = ArcsJoiner{BevelJoin, 4.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 the limit, this will result in a bevel join (ArcsJoin) or they will meet at the limit (ArcsClipJoin).

var BevelJoin Joiner = BevelJoiner{}

BevelJoin connects two path elements by a linear join.

var MiterClipJoin Joiner = MiterJoiner{nil, 4.0}
var MiterJoin Joiner = MiterJoiner{BevelJoin, 4.0}

MiterJoin connects two path elements by extending the ends of the paths as lines until they meet. If this point is further than the limit, this will result in a bevel join (MiterJoin) or they will meet at the limit (MiterClipJoin).

var RoundJoin Joiner = RoundJoiner{}

RoundJoin connects two path elements by a round join.

type LinearColorSpace

type LinearColorSpace struct{}

LinearColorSpace is the default color space that does not do color space conversion for blending purposes. This is only correct if the input colors and output images are assumed to be in the linear color space so that blending is in linear space as well. In general though, we assume that input colors and output images are using the sRGB color space almost ubiquitously, resulting in blending in sRGB space which is wrong! Even though it is technically incorrect, many PDF viewers and browsers do this anyway.

func (LinearColorSpace) FromLinear

func (LinearColorSpace) FromLinear(col color.Color) color.RGBA

FromLinear decodes color from color space.

func (LinearColorSpace) ToLinear

func (LinearColorSpace) ToLinear(col color.Color) color.RGBA

ToLinear encodes color to color space.

type LinearGradient

type LinearGradient struct {
	Start, End Point
	Stops
	// contains filtered or unexported fields
}

LinearGradient is a linear gradient pattern between the given start and end points. The color at offset 0 corresponds to the start position, and offset 1 to the end position. Start and end points are in the canvas's coordinate system.

func NewLinearGradient

func NewLinearGradient(start, end Point) *LinearGradient

NewLinearGradient returns a new linear gradient pattern.

func (*LinearGradient) At

func (g *LinearGradient) At(x, y float64) color.RGBA

At returns the color at position (x,y).

func (*LinearGradient) SetColorSpace

func (g *LinearGradient) SetColorSpace(colorSpace ColorSpace) Gradient

SetColorSpace sets the color space. Automatically called by the rasterizer.

func (*LinearGradient) SetView

func (g *LinearGradient) SetView(view Matrix) Gradient

SetView sets the view. Automatically called by Canvas for coordinate system transformations.

type Matrix

type Matrix [2][3]float64

Matrix is used for affine transformations, which are transformations such as translation, scaling, reflection, rotation, shear stretching. See https://en.wikipedia.org/wiki/Affine_transformation#Image_transformation for an overview of the transformations. The affine transformation matrix contains all transformations in a matrix, where we can concatenate transformations to apply them sequentially. Be aware that concatenated transformations 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 ParallelogramCell

func ParallelogramCell(a, b, rot float64) Matrix

ParallelogramCell is a paralellogram cell with sides of length a and b at an angle of rot degrees used for tiling.

func PrimitiveCell

func PrimitiveCell(a, b Point) Matrix

PrimitiveCell is a (primitive) cell used for tiling.

func RectangleCell

func RectangleCell(a, b float64) Matrix

RectangleCell is a rectangular cell with width a and height b used for tiling.

func RhombusCell

func RhombusCell(a float64) Matrix

RhombusCell is a rhombus cell with sides of length a at an angle of 120 degrees used for tiling.

func SquareCell

func SquareCell(a float64) Matrix

SquareCell is a square cell with sides of length a used for tiling.

func TileRectangle

func TileRectangle(cell Matrix, dst, src Rect) []Matrix

TileRectangle tiles the given cell (determines the axes along which cells are repeated) onto the rectangle dst (bounds of clipping path), where cells are filled by rectangle src (bounds of object to be tiled).

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(phi).Scale(sx, sy).Rotate(theta).

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, i.e. applying the 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 is orthogonal and consists of only translation, rotation, and reflection transformations.

func (Matrix) IsSimilarity

func (m Matrix) IsSimilarity() bool

IsSimilarity is true if the matrix consists of only translation, rotation, reflection, and scaling transformations.

func (Matrix) IsTranslation

func (m Matrix) IsTranslation() bool

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

func (Matrix) Mul

func (m Matrix) Mul(q Matrix) Matrix

Mul multiplies the current matrix by the given matrix, i.e. combining 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, i.e. Scale(-1,1).

func (Matrix) ReflectXAbout

func (m Matrix) ReflectXAbout(x float64) Matrix

ReflectXAbout adds a horizontal reflection transformation about x.

func (Matrix) ReflectY

func (m Matrix) ReflectY() Matrix

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

func (Matrix) ReflectYAbout

func (m Matrix) ReflectYAbout(y float64) Matrix

ReflectYAbout adds a vertical reflection transformation about 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 about (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 about (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 about (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 Paint

type Paint struct {
	Color color.RGBA
	Gradient
	Pattern
}

Paint is the type of paint used to fill or stroke a path. It can be either a color or a pattern. Default is transparent (no paint).

func (Paint) Equal

func (paint Paint) Equal(other Paint) bool

Equal returns true if Paints are equal.

func (Paint) Has

func (paint Paint) Has() bool

Has returns true if paint has a color or pattern.

func (Paint) IsColor

func (paint Paint) IsColor() bool

IsColor returns true when paint is a uniform color.

func (Paint) IsGradient

func (paint Paint) IsGradient() bool

IsGradient returns true when paint is a gradient.

func (Paint) IsPattern

func (paint Paint) IsPattern() bool

IsPattern returns true when paint is a pattern.

type Path

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

Path defines a vector path in 2D using a series of 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 is 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 in the range [0, 2*PI) and we scale the radii up if they appear too small to fit the arc.

func Arc

func Arc(r, theta0, theta1 float64) *Path

Arc returns a circular arc with radius r 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, e.g. a difference of 810 degrees will draw one full circle and an arc over 90 degrees.

func BeveledRectangle

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

BeveledRectangle returns a rectangle of 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 of radius r.

func Ellipse

func Ellipse(rx, ry float64) *Path

Ellipse returns an ellipse of radii rx and ry.

func EllipticalArc

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

EllipticalArc returns 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, e.g. a difference of 810 degrees will draw one full circle and an arc over 90 degrees.

func Grid

func Grid(w, h float64, nx, ny int, r float64) *Path

Grid returns a stroked grid of width w and height h, with grid line thickness r, and the number of cells horizontally and vertically as nx and ny respectively.

func Line

func Line(x, y float64) *Path

Line returns a line segment of from (0,0) to (x,y).

func MustParseSVGPath

func MustParseSVGPath(s string) *Path

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

func ParseSVGPath

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

ParseSVGPath parses an SVG path data string.

func Rectangle

func Rectangle(w, h float64) *Path

Rectangle returns a rectangle of width w and height h.

func RegularPolygon

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

RegularPolygon returns a regular polygon with radius r. 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 upwards or downwards.

func RegularStarPolygon

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

RegularStarPolygon returns a regular star polygon with radius r. 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 upwards or downwards.

func RoundedRectangle

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

RoundedRectangle returns a rectangle of width w and height h with rounded corners of radius r. A negative radius will cast the corners inwards (i.e. 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 will be point upwards or downwards.

func Triangle

func Triangle(r float64) *Path

Triangle returns a triangle of radius r pointing upwards.

func (*Path) And

func (p *Path) And(q *Path) *Path

And returns the boolean path operation of path p and q. Path q is implicitly closed.

func (*Path) Append

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

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

func (*Path) Arc

func (p *Path) 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, e.g. 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)

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's end point.

func (*Path) Bounds

func (p *Path) Bounds() Rect

Bounds returns the exact 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. It implictly closes open paths and will return true for a empty or straight line.

func (*Path) Close

func (p *Path) Close()

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) Collisions

func (p *Path) Collisions(q *Path) ([]PathIntersection, []PathIntersection)

Collisions (secants/intersections and tangents/touches) for path p by path q, sorted for path p.

func (*Path) Contains

func (p *Path) Contains(x, y float64) bool

Contains returns whether the path contains the point (x,y) in any of its subpaths.

func (*Path) ContainsPath

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

ContainsPath returns true if path q is contained within path p, i.e. path q is inside path p and both paths have no intersections (but may touch). Paths must have been settled to remove self-intersections.

func (*Path) CoordDirections

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

CoordDirections returns the direction of the segment start/end points. It will return the average direction at the intersection of two end points, and for an open path it will simply return the direction of the start and end points of the path.

func (*Path) Coords

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

Coords returns all the coordinates of the segment start/end points. It omits zero-length CloseCmds.

func (*Path) Copy

func (p *Path) Copy() *Path

Copy returns a copy of p.

func (*Path) Crossings

func (p *Path) Crossings(x, y float64) (int, bool)

Crossings returns the number of crossings wiht the path from the given point outwards, i.e. the number of times a ray from (x,y) towards (∞,y) intersects the path. Additionally, it returns whether the point is on a path's boundary (which does not count towards the number of crossings).

func (*Path) CubeTo

func (p *Path) 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 (*Path) Cut

func (p *Path) Cut(q *Path) []*Path

Cut cuts path p by path q and returns the parts.

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 into the path). Dash will be applied to each subpath independently.

func (*Path) Data

func (p *Path) Data() []float64

Data returns the raw path data.

func (*Path) DivideBy

func (p *Path) DivideBy(q *Path) *Path

DivideBy returns the division of path p by path q at intersections.

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) FastBounds

func (p *Path) FastBounds() Rect

FastBounds returns the maximum bounding box rectangle of the path. It is quicker than Bounds.

func (*Path) Filling

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

Filling returns whether each subpath gets filled or not. Whether a path is filled depends on the FillRule and whether it negates another path. If a subpath is not closed, it is implicitly assumed to be closed. Subpaths must not self-intersect, use Settle to remove self-intersections.

func (*Path) Fills

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

Fills returns whether the point (x,y) is filled by the path. This depends on the FillRule. It uses a ray from (x,y) toward (∞,y) and counts the number of intersections with the path. When the point is on the boundary it is considered to be exterior.

func (*Path) Flat

func (p *Path) Flat() bool

Flat returns true if the path consists of solely line segments, that is only MoveTo, LineTo and Close commands.

func (*Path) Flatten

func (p *Path) Flatten(tolerance float64) *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) HasSubpaths

func (p *Path) HasSubpaths() bool

HasSubpaths returns true when path p has subpaths. TODO: naming right? A simple path would not self-intersect. Add XMonotone and Flat as well

func (*Path) InteriorPoint

func (p *Path) InteriorPoint() Point

InteriorPoint returns a point on the interior of the path. The path should be a non-complex non-self-intersecting path (i.e. settled with no subpaths). It uses the first subpath if there are multiple and returns the start position on open paths.

func (*Path) Intersections

func (p *Path) Intersections(q *Path) ([]PathIntersection, []PathIntersection)

Intersections for path p by path q, sorted for path p.

func (*Path) Intersects

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

Intersects returns true if path p and path q intersect.

func (*Path) Join

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

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

func (*Path) Len

func (p *Path) Len() int

Len returns the number of segments.

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)

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 marker paths along the path at the 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)

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 depends on the FillRule.

func (*Path) Not

func (p *Path) Not(q *Path) *Path

Not returns the boolean path operation of path p and q. Path q is implicitly closed.

func (*Path) Offset

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

Offset offsets the path to expand by w and returns a new path. If w is negative it will contract. For open paths, a positive w will offset the path to the right-hand side. The tolerance is the maximum deviation from the actual offset when flattening Béziers and optimizing the path. Subpaths may not (self-)intersect, use Settle to remove (self-)intersections.

func (*Path) Or

func (p *Path) Or(q *Path) *Path

Or returns the boolean path operation of path p and q. Path q is implicitly closed.

func (*Path) PointClosed

func (p *Path) PointClosed() bool

PointClosed returns true if the last subpath of p is a closed path and the close command is a point and not a line.

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)

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

func (*Path) RayIntersections

func (p *Path) RayIntersections(x, y float64) []PathIntersection

RayIntersections returns the intersections of a path with a ray starting at (x,y) to (∞,y). An intersection is tangent only when it is at (x,y), i.e. the start of the ray. Intersections are sorted along the ray.

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) ReverseScanner

func (p *Path) ReverseScanner() *PathReverseScanner

ReverseScanner returns a path scanner in reverse order.

func (*Path) Same

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

Same returns true if p and q are equal shapes within tolerance Epsilon. Path q may start at an offset into path p or may be in the reverse direction.

func (*Path) Scale

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

Scale scales the path by (x,y) and returns a new path.

func (*Path) Scanner

func (p *Path) Scanner() *PathScanner

Scanner returns a path scanner.

func (*Path) Settle

func (p *Path) Settle(fillRule FillRule) *Path

Settle simplifies a path by removing all self-intersections and overlapping parts. Open paths are not handled and returned as-is. The returned subpaths are oriented counter clock-wise when filled and clock-wise for holes. This means that the result is agnostic to the winding rule used for drawing. The result will only contain point-tangent intersections, but not parallel-tangent intersections or regular intersections. See L. Subramaniam, "Partition of a non-simple polygon into simple pologons", 2003

func (*Path) Split

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

Split splits the path into its independent subpaths. The path is split before each MoveTo command.

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, i.e. 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, tolerance float64) *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 elements. 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) Tile

func (p *Path) Tile(clip *Path, cell Matrix) *Path

Tile tiles a path within a clipping path using the given primitive cell.

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, resolution Resolution)

ToRasterizer rasterizes the path using the given rasterizer and resolution.

func (*Path) ToSVG

func (p *Path) ToSVG() string

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

func (*Path) Touches

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

Touches returns true if path p and path q touch or intersect.

func (*Path) Transform

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

Transform transforms 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.

func (*Path) Triangulate

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

Triangulate tessellates the path with triangles that fill the path. WIP

func (*Path) Windings

func (p *Path) Windings(x, y float64) (int, bool)

Windings returns the number of windings at the given point, i.e. the sum of windings for each time a ray from (x,y) towards (∞,y) intersects the path. Counter clock-wise intersections count as positive, while clock-wise intersections count as negative. Additionally, it returns whether the point is on a path's boundary (which counts as being on the exterior).

func (*Path) XMonotone

func (p *Path) XMonotone() bool

XMonotone returns true if the path is x-monotone, that is each path segment is either increasing or decreasing with X while moving across the segment. This is always true for line segments, but may not be the case for Beziér or arc segments.

func (*Path) Xor

func (p *Path) Xor(q *Path) *Path

Xor returns the boolean path operation of path p and q. Path q is implicitly closed.

type PathIntersection

type PathIntersection struct {
	Point         // coordinate of intersection
	Seg   int     // segment index
	T     float64 // position along segment [0,1]
	Dir   float64 // direction at intersection

	Into     bool // going forward, path goes to LHS of other path
	Parallel bool // going forward, paths are parallel
	Tangent  bool // intersection is tangent (touches) instead of secant (crosses)
}

PathIntersection is an intersection of a path. Intersection is either tangent or secant. Tangent intersections may be Parallel. Secant intersections either go into the other path (Into is set) or the other path goes into this path (Into is not set). Possible types of intersections:

  • Crossing anywhere: Tangent=false, Parallel=false
  • Touching anywhere: Tangent=true, Parallel=false, Into is invalid
  • Parallel onwards: Tangent=false, Parallel=true, Into is invalid

NB: Tangent may also be true for non-closing paths when touching its endpoints

func (PathIntersection) Equals

func (PathIntersection) Less

func (PathIntersection) String

func (z PathIntersection) String() string

type PathIntersectionNode

type PathIntersectionNode struct {
	PintoQ           bool
	Tangent          bool
	Parallel         bool
	ParallelReversed bool
	// contains filtered or unexported fields
}

func (PathIntersectionNode) ParallelTangent

func (z PathIntersectionNode) ParallelTangent(onP, forwardP, forwardQ bool) bool

func (PathIntersectionNode) String

func (z PathIntersectionNode) String() string

type PathReverseScanner

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

PathReverseScanner scans the path in reverse order.

func (*PathReverseScanner) Arc

Arc returns the arguments for arcs (rx,ry,rot,large,sweep).

func (*PathReverseScanner) CP1

func (s *PathReverseScanner) CP1() Point

CP1 returns the first control point for quadratic and cubic Béziers.

func (*PathReverseScanner) CP2

func (s *PathReverseScanner) CP2() Point

CP2 returns the second control point for cubic Béziers.

func (*PathReverseScanner) Cmd

func (s *PathReverseScanner) Cmd() float64

Cmd returns the current path segment command.

func (*PathReverseScanner) End

func (s *PathReverseScanner) End() Point

End returns the current path segment end position.

func (*PathReverseScanner) Path

func (s *PathReverseScanner) Path() *Path

Path returns the current path segment.

func (*PathReverseScanner) Scan

func (s *PathReverseScanner) Scan() bool

Scan scans a new path segment and should be called before the other methods.

func (*PathReverseScanner) Start

func (s *PathReverseScanner) Start() Point

Start returns the current path segment start position.

func (*PathReverseScanner) Values

func (s *PathReverseScanner) Values() []float64

Values returns the current path segment values.

type PathScanner

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

PathScanner scans the path.

func (*PathScanner) Arc

func (s *PathScanner) Arc() (float64, float64, float64, bool, bool)

Arc returns the arguments for arcs (rx,ry,rot,large,sweep).

func (*PathScanner) CP1

func (s *PathScanner) CP1() Point

CP1 returns the first control point for quadratic and cubic Béziers.

func (*PathScanner) CP2

func (s *PathScanner) CP2() Point

CP2 returns the second control point for cubic Béziers.

func (*PathScanner) Cmd

func (s *PathScanner) Cmd() float64

Cmd returns the current path segment command.

func (*PathScanner) End

func (s *PathScanner) End() Point

End returns the current path segment end position.

func (*PathScanner) Path

func (s *PathScanner) Path() *Path

Path returns the current path segment.

func (*PathScanner) Scan

func (s *PathScanner) Scan() bool

Scan scans a new path segment and should be called before the other methods.

func (*PathScanner) Start

func (s *PathScanner) Start() Point

Start returns the current path segment start position.

func (*PathScanner) Values

func (s *PathScanner) Values() []float64

Values returns the current path segment values.

type Pattern

type Pattern interface {
	SetView(Matrix) Pattern
	SetColorSpace(ColorSpace) Pattern
	ClipTo(Renderer, *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 EllipsePos

func EllipsePos(rx, ry, phi, cx, cy, theta float64) Point

EllipsePos returns the position on the ellipse at angle theta.

func PolarPoint

func PolarPoint(angle, radius float64) Point

PolarPoint returns a point from polar coordinates, with angle in radians CCW and radius the distance from (0,0).

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 [0,2PI) 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, i.e. 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) Hadamard

func (p Point) Hadamard(q Point) Point

Hadamard returns the Hadamard product, or the element-wise product, of the point.

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], i.e. 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 normalises 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, i.e. zero if aligned and |OP|*|OQ| if perpendicular. This is the cross product in two dimensions.

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, i.e. 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, i.e. by 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, i.e. 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) Area

func (p *Polyline) Area() float64

Area returns the polygon's signed area.

func (*Polyline) Centroid

func (p *Polyline) Centroid() Point

Centroid returns the center point of the polygon.

func (*Polyline) Close

func (p *Polyline) Close() *Polyline

Close adds a new point equal to the first, closing the polyline.

func (*Polyline) Closed

func (p *Polyline) Closed() bool

Closed returns true if the last point coincides with the first.

func (*Polyline) Coords

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

Coords returns the list of coordinates of the polyline.

func (*Polyline) Empty

func (p *Polyline) Empty() bool

Empty returns true if the polyline is empty.

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, i.e. gets filled. This depends on the FillRule.

func (*Polyline) Len

func (p *Polyline) Len() int

Len returns the number of segments.

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 segments too.

func (*Polyline) ToPath

func (p *Polyline) ToPath() *Path

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

type RadialGradient

type RadialGradient struct {
	C0, C1 Point
	R0, R1 float64
	Stops
	// contains filtered or unexported fields
}

RadialGradient is a radial gradient pattern between two circles defined by their center points and radii. Color stop at offset 0 corresponds to the first circle and offset 1 to the second circle.

func NewRadialGradient

func NewRadialGradient(c0 Point, r0 float64, c1 Point, r1 float64) *RadialGradient

NewRadialGradient returns a new radial gradient pattern.

func (*RadialGradient) At

func (g *RadialGradient) At(x, y float64) color.RGBA

At returns the color at position (x,y).

func (*RadialGradient) SetColorSpace

func (g *RadialGradient) SetColorSpace(colorSpace ColorSpace) Gradient

SetColorSpace sets the color space. Automatically called by the rasterizer.

func (*RadialGradient) SetView

func (g *RadialGradient) SetView(view Matrix) Gradient

SetView sets the view. Automatically called by Canvas for coordinate system transformations.

type Rect

type Rect struct {
	// TODO: better with X0,Y0,X1,Y1
	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) AddPoint

func (r Rect) AddPoint(p Point) Rect

AddPoint returns a rect that encompasses both the current rect and the given point.

func (Rect) Contains

func (r Rect) Contains(p Point) bool

Contains returns true if the rectangles contains a point, not if it touches an edge.

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) Overlaps

func (r Rect) Overlaps(q Rect) bool

Overlaps returns true if both rectangles overlap.

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 images.

type Resolution

type Resolution float64

Resolution is used for rasterizing. Higher resolutions will result in larger images.

func DPI

func DPI(dpi float64) Resolution

DPI (dots-per-inch) for the resolution of rasterization.

func DPMM

func DPMM(dpmm float64) Resolution

DPMM (dots-per-millimeter) for the resolution of rasterization.

func (Resolution) DPI

func (res Resolution) DPI() float64

DPI returns the resolution in dots-per-inch.

func (Resolution) DPMM

func (res Resolution) DPMM() float64

DPMM returns the resolution in dots-per-millimeter.

type RichText

type RichText struct {
	*strings.Builder
	// contains filtered or unexported fields
}

RichText allows to build up a rich text with text spans of different font faces and fitting that into a box using Donald Knuth's line breaking algorithm.

func NewRichText

func NewRichText(face *FontFace) *RichText

NewRichText returns a new rich text with the given default font face.

func (*RichText) Add

func (rt *RichText) Add(face *FontFace, text string) *RichText

func (*RichText) AddCanvas

func (rt *RichText) AddCanvas(c *Canvas, valign VerticalAlign) *RichText

func (*RichText) AddImage

func (rt *RichText) AddImage(img image.Image, res Resolution, valign VerticalAlign) *RichText

func (*RichText) AddPath

func (rt *RichText) AddPath(path *Path, col color.RGBA, valign VerticalAlign) *RichText

func (*RichText) Reset

func (rt *RichText) Reset()

Reset resets the rich text to its initial state.

func (*RichText) SetFace

func (rt *RichText) SetFace(face *FontFace)

SetFace sets the font face.

func (*RichText) SetFaceSpan

func (rt *RichText) SetFaceSpan(face *FontFace, start, end int)

SetFaceSpan sets the font face between start and end measured in bytes.

func (*RichText) SetTextOrientation

func (rt *RichText) SetTextOrientation(orient TextOrientation)

SetTextOrientation sets the text orientation of non-CJK between CJK.

func (*RichText) SetWritingMode

func (rt *RichText) SetWritingMode(mode WritingMode)

SetWritingMode sets the writing mode.

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 using Donald Knuth's line breaking algorithm.

func (*RichText) WriteCanvas

func (rt *RichText) WriteCanvas(c *Canvas, valign VerticalAlign)

WriteCanvas writes an inline canvas object.

func (*RichText) WriteFace

func (rt *RichText) WriteFace(face *FontFace, text string)

WriteFace writes a string with a given font face.

func (*RichText) WriteImage

func (rt *RichText) WriteImage(img image.Image, res Resolution, valign VerticalAlign)

WriteImage writes an inline image.

func (*RichText) WritePath

func (rt *RichText) WritePath(path *Path, col color.RGBA, valign VerticalAlign)

WritePath writes an inline path.

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 SRGBColorSpace

type SRGBColorSpace struct{}

SRGBColorSpace assumes that input colors and output images are in the sRGB color space (ubiquitous in almost all applications), which implies that for blending we need to convert to the linear color space, do blending, and then convert back to the sRGB color space. This will give technically correct blending, but may differ from common PDF viewer and browsers (which are wrong).

func (SRGBColorSpace) FromLinear

func (SRGBColorSpace) FromLinear(col color.Color) color.RGBA

FromLinear decodes color from color space.

func (SRGBColorSpace) ToLinear

func (SRGBColorSpace) ToLinear(col color.Color) color.RGBA

ToLinear encodes color to color space.

type Segment

type Segment struct {
	Cmd        float64
	Start, End Point
	// contains filtered or unexported fields
}

Segment is a path command.

func (Segment) Arc

func (seg Segment) Arc() (float64, float64, float64, bool, bool)

Arc returns the arguments for arcs (rx,ry,rot,large,sweep).

func (Segment) CP1

func (seg Segment) CP1() Point

CP1 returns the first control point for quadratic and cubic Béziers.

func (Segment) CP2

func (seg Segment) CP2() Point

CP2 returns the second control point for cubic Béziers.

type Size

type Size struct {
	W, H float64
}

Size defines a size (width and height).

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 Stop

type Stop struct {
	Offset float64
	Color  color.RGBA
}

Stop is a color and offset for gradient patterns.

type Stops

type Stops []Stop

Stops are the colors and offsets for gradient patterns, sorted by offset.

func (*Stops) Add

func (stops *Stops) Add(t float64, color color.RGBA)

Add adds a new color stop to a gradient.

func (Stops) At

func (stops Stops) At(t float64) color.RGBA

At returns the color at position t ∈ [0,1].

type Style

type Style struct {
	Fill         Paint
	Stroke       Paint
	StrokeWidth  float64
	StrokeCapper Capper
	StrokeJoiner Joiner
	DashOffset   float64
	Dashes       []float64
	FillRule     // TODO: test for all renderers
}

Style is the path style that defines how to draw the path. When Fill is not set 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).

func (Style) HasFill

func (style Style) HasFill() bool

HasFill returns true if the style has a fill

func (Style) HasStroke

func (style Style) HasStroke() bool

HasStroke returns true if the style has a stroke

func (Style) IsDashed

func (style Style) IsDashed() bool

IsDashed returns true if the style has dashes

type Text

type Text struct {
	WritingMode
	TextOrientation
	Width, Height float64
	Text          string
	Overflows     bool // true if lines stick out of the box
	// contains filtered or unexported fields
}

Text holds the representation of a text object.

func NewTextBox

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

NewTextBox is an advanced text formatter that will format text placement based on the settings. It takes a single font face, a string, the width or height of the box (can be zero to disable), 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(face *FontFace, s string, halign TextAlign) *Text

NewTextLine is a simple text line using a single font face, a string (supporting new lines) and horizontal alignment (Left, Center, Right). The text's baseline will be drawn on the current coordinate.

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 returns true if there are no text lines or text spans.

func (*Text) Fonts

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

Fonts returns the list of fonts used.

func (*Text) Heights

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

Heights returns the top and bottom position of the first and last line respectively.

func (*Text) Lines

func (t *Text) Lines() int

Lines returns the number of text lines of the text box.

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, i.e. the glyph outlines (slow).

func (*Text) RenderAsPath

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

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

func (*Text) Size

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

Size returns the width and height of a text box. Either can be zero when unspecified.

func (*Text) String

func (t *Text) String() string

String returns the content of the text box.

func (*Text) WalkDecorations

func (t *Text) WalkDecorations(callback func(fill Paint, deco *Path))

WalkDecorations calls the callback for each color of decoration used per line.

func (*Text) WalkLines

func (t *Text) WalkLines(callback func(float64, []TextSpan))

WalkLines calls the callback for each text line.

func (*Text) WalkSpans

func (t *Text) WalkSpans(callback func(float64, float64, TextSpan))

WalkSpans calls the callback for each text span per line.

type TextAlign

type TextAlign int

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

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

see TextAlign

func (TextAlign) String

func (ta TextAlign) String() string

type TextOrientation

type TextOrientation int

TextOrientation specifies how horizontal text should be oriented within vertical text, or how vertical-only text should be laid out in horizontal text.

const (
	Natural TextOrientation = iota // turn horizontal text 90deg clockwise for VerticalRL, and counter clockwise for VerticalLR
	Upright                        // split characters and lay them out upright
)

see TextOrientation

func (TextOrientation) String

func (orient TextOrientation) String() string

type TextSpan

type TextSpan struct {
	X         float64
	Width     float64
	Face      *FontFace
	Text      string
	Glyphs    []text.Glyph
	Direction text.Direction
	Rotation  text.Rotation
	Level     int

	Objects []TextSpanObject
}

TextSpan is a span of text.

func (*TextSpan) IsText

func (span *TextSpan) IsText() bool

IsText returns true if the text span is text and not objects (such as images or paths).

type TextSpanObject

type TextSpanObject struct {
	*Canvas
	X, Y          float64
	Width, Height float64
	VAlign        VerticalAlign
}

TextSpanObject is an object that can be used within a text span. It is a wrapper around Canvas and can thus draw anything to be mixed with text, such as images (emoticons) or paths (symbols).

func (TextSpanObject) Heights

func (obj TextSpanObject) Heights(face *FontFace) (float64, float64)

Heights returns the ascender and descender values of the span object.

func (TextSpanObject) View

func (obj TextSpanObject) View(x, y float64, face *FontFace) Matrix

View returns the object's view to be placed within the text line.:

type VerticalAlign

type VerticalAlign int

VerticalAlign specifies how the object should align vertically when embedded in text.

const (
	Baseline VerticalAlign = iota
	FontTop
	FontMiddle
	FontBottom
)

see VerticalAlign

func (VerticalAlign) String

func (valign VerticalAlign) String() string

type Writer

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

Writer can write a canvas to a writer.

type WritingMode

type WritingMode int

WritingMode specifies how the text lines should be laid out.

const (
	HorizontalTB WritingMode = iota
	VerticalRL
	VerticalLR
)

see WritingMode

func (WritingMode) String

func (wm WritingMode) String() string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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