Graphics2D is a vector based drawing package that leverages golang.org/x/image/vector to render shapes into an image.
The vector package works by extending image/draw to create a mask, that the source image is rendered through, into the underlying destination image. The graphics2d package follows this convention.
All the pictures and diagrams in this README are created with this package. Clicking on one will take you to the code that creates it.
The primary type in the package is the Path. A path represents a single movement of a pen, from pen down to pen up. Paths are composed of steps with some number of points in them. The number of points determines the order of the Bezier curve generated. The path methods LineTo and CurveTo are just synonyms for AddStep. Once created, a path can be left as is (open), or closed Close. A closed path can not be extended and a line is automatically created from its last point to its first, if necessary.
Shapes allow multiple paths to be combined to produce more complex drawings. For example, the figure 8 is composed of three paths; its external outline, and the two holes in it.
Shapes are rendered to an image using a source image and the mask generated from the shape, by RenderShape. If the source is a single color, then RenderColoredShape can be used.
These shapes were created using Line, RegularPolygon, Circle, and Oval. These are just some of the constructors available for the Path type.
Bezier curves are polynomial curves. While most vector packages support first, second and third order curves; lines, quadratic and cubic curves respectively, the path AddStep method has no upper limit on the number of control points that can be specified, allowing the creation of higher order curves. The last example on the right is a quartic curve.
Various arc path constructors are available and typically take a start angle and a sweep angle. The sign of the sweep angle determines whether it goes clockwise or counter-clockwise. The arcs are approximated from cubic Bezier curves. Arcs must have an ArcStyle associated with them, one of ArcOpen, ArcPie or ArcChord as shown above.
Examples of different regular reentrant polygons made with ReentrantPolygon. The degree of reentrancy is controlled by a value in the range [0,1) where 0 represents a regular polygon and 1, a polygon with no area. A value of 0.5 was used for these polygons.
Paths have a Process method that allows a PathProcessor to be applied to them which will generate one or more new paths. This example shows what the effect of the CurveProc looks like applied to both a closed and an open path made up of multiple line segments. CurveProc requires a CurveStyle to be specified too, one of Quad, Bezier or CatmullRom (L to R in the example).
Another path processor that can be used to create curved paths is RoundedProc. This example uses increasing curve radii from L to R.
Path processors can be chained together to produce more sophisticated paths using CompoundProc. This path processor provides an option to concatenate paths prior to running the next path processor.
Shapes have a similar function ProcessPaths which runs a path processor over all of the paths in a shape.
The golang.org/x/image/font/sfnt package can load TrueType and OpenType fonts. Strings can be turned into shapes using such a font and StringToShape. The shapes will be sized in font units, the space the font glyphs were originally specified in. ScaleAndInset can be used to fit the result to the desired location. This example also uses path processors to show the control points for the font curves.
These were created from the paths in the earlier example using the DashProc path processor. The dash patterns are {4, 2}, {8, 2, 2, 2} and {10, 4}. The bottom row also uses another path processor, CapsProc, on the paths from running DashProc, to add the arrow heads.
The TraceProc path processor traces a path, either to the left or the right of the original, depending on the offset value supplied. How path steps are joined is specified by a join function that the processor calls. The following functions are shown: JoinButt, JoinRound, and JoinMiter.
A variable width trace path processor,
VWTraceProc,
uses the distance along the path, t (range [0,1]), to figure the current offset of the trace.
This example uses (1-t) * offset as the offset function.
The joins are all miter joins, implicitly.
The StrokeProc is used to convert open paths to closed ones, since only closed paths are filled by the renderer.
A stroke is comprised of left and right trace path processors, and functions that define the start and end caps of the path.
This example shows the CapButt, CapSquare, CapRoundedSquare, CapInvRound and CapRound, CapInvOval and CapOval, and CapInvPoint and CapPoint, from left to right.
End caps are only used when the path is open. When a stroke processor is applied to a closed path, two closed paths are created forming an outline of the original.
A Pen is a convenient abstraction that ties together a filler image, a path processor, and a transform. The path processor creates the closed paths needed for rendering, so that the user doesn't have to write the mechanics of outlining for every shape. The transform is applied to the shape prior to the path processor so a pen with width 1, for example, will draw paths with width 1 in the image and not the shape coordinates. A predefined collection of colored pens is available here. Dashed pens can be constructed by concatenating DashProc with the path processor. See the pen example.
Convenience functions that take a pen argument are:
Gradients aren't strictly part of the graphics2d package since a shape just defines a mask through which the source image is rendered into the destination. Source images containing gradients can be created using the texture package. This package supports linear, radial, elliptical and conic gradients with convenience functions for gray scale and RGBA images. The gradients can be set to repeat and to mirror. The RGBA gradients are just Colorizer wrappers around their Gray16 counterparts, allowing for multiple color stops in the gradient.
List of gradient image functions:
- NewLinearGray16
- NewRadialGray16
- NewEllipticalGray16
- NewConicGray16
- NewLinearRGBA
- NewRadialRGBA
- NewEllipticalRGBA
- NewConicRGBA
Text, JSON and XML (as SVG) marshaling of shapes and paths is supported. See the examples in the documentation.
Unmarshaling is only supported for text and JSON.
See the separate README for more details on how SVG rendering works.
Shapes are rendered as their masks using whatever source image is provided. A shape's mask is obtained using its Mask method. The mask image can be further manipulated or used for clipping prior to DrawMask being called. An example is provided in this gist, which shows a watercolor like effect of dye pooling at a brush stroke's edge by applying a blur to the mask, inverting it, and then masking it with the original mask.












