raster

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Apr 14, 2024 License: BSD-3-Clause Imports: 5 Imported by: 0

README

Raster

Raster is a golang rasterizer that implements path stroking functions capable of SVG 2.0 compliant 'arc' joins and explicit loop closing.

  • Paths can be explicitly closed or left open, resulting in a line join or end caps.
  • Arc joins are supported, which causes the extending edge from a Bezier curve to follow the radius of curvature at the end point rather than a straight line miter, resulting in a more fluid looking join.
  • Not specified in the SVG2.0 spec., but supported in raster is the arc-clip join, which is the arc join analog of a miter-clip join, both of which end the miter at a specified distance, rather than all or nothing.
  • Several cap and gap functions in addition to those specified by SVG2.0 are implemented, specifically quad and cubic caps and gaps.
  • Line start and end capping functions can be different.

rasterx example

The above image shows the effect of using different join modes for a stroked curving path. The top stroked path uses miter (green) or arc (red, yellow, orange) join functions with high miter limit. The middle and lower path shows the effect of using the miter-clip and arc-clip joins, repectively, with different miter-limit values. The black chevrons at the top show different cap and gap functions.

Scanner interface

Rasterx takes the path description of lines, bezier curves, and drawing parameters, and converts them into a set of straight line segments before rasterizing the lines to an image using some method of antialiasing. Rasterx abstracts this last step through the Scanner interface. There are two different structs that satisfy the Scanner interface; ScannerGV and ScannerFT. ScannerGV wraps the rasterizer found in the golang.org/x/image/vector package. ScannerFT contains a modified version of the antialiaser found in the golang freetype translation. These use different functions to connect an image to the antialiaser. ScannerFT uses a Painter to translate the raster onto the image, and ScannerGV uses the vector's Draw method with a source image and uses the path as an alpha mask. Please see the test files for examples. At this time, the ScannerFT is a bit faster as compared to ScannerGV for larger and less complicated images, while ScannerGV can be faster for smaller and more complex images. Also ScannerGV does not allow for using the even-odd winding rule, which is something the SVG specification uses. Since ScannerFT is subject to freetype style licensing rules, it lives here in a separate repository and must be imported into your project separately. ScannerGV is included in the rasterx package, and has more go-friendly licensing.

Below are the results of some benchmarks performed on a sample shape (the letter Q ). The first test is the time it takes to scan the image after all the curves have been flattened. The second test is the time it takes to flatten, and scan a simple filled image. The last test is the time it takes to flatten a stroked and dashed outline of the shape and scan it. Results for three different image sizes are shown.

128x128 Image
Test                        Rep       Time
BenchmarkScanGV-16          5000      287180 ns/op
BenchmarkFillGV-16          5000      339831 ns/op
BenchmarkDashGV-16          2000      968265 ns/op

BenchmarkScanFT-16    	   20000       88118 ns/op
BenchmarkFillFT-16    	    5000      214370 ns/op
BenchmarkDashFT-16    	    1000     2063797 ns/op

256x256 Image
Test                        Rep       Time
BenchmarkScanGV-16          2000     1188452 ns/op
BenchmarkFillGV-16          1000     1277268 ns/op
BenchmarkDashGV-16          500      2238169 ns/op

BenchmarkScanFT-16    	    5000      290685 ns/op
BenchmarkFillFT-16    	    3000      446329 ns/op
BenchmarkDashFT-16    	     500     2923512 ns/op

512x512 Image
Test                        Rep       Time
BenchmarkScanGV-16           500     3341038 ns/op
BenchmarkFillGV-16           500     4032213 ns/op
BenchmarkDashGV-16           200     6003355 ns/op

BenchmarkScanFT-16    	    5000      292884 ns/op
BenchmarkFillFT-16    	    3000      449582 ns/op
BenchmarkDashFT-16    	     500     2800493 ns/op

The package uses an interface called Rasterx, which is satisfied by three structs, Filler, Stroker and Dasher. The Filler flattens Bezier curves into lines and uses an anonymously composed Scanner for the antialiasing step. The Stroker embeds a Filler and adds path stroking, and the Dasher embedds a Stroker and adds the ability to create dashed stroked curves.

rasterx Scheme

Each of the Filler, Dasher, and Stroker can function on their own and each implement the Rasterx interface, so if you need just the curve filling but no stroking capability, you only need a Filler. On the other hand if you have created a Dasher and want to use it to Fill, you can just do this:

filler := &dasher.Filler

Now filler is a filling rasterizer. Please see rasterx_test.go for examples.

Non-standard library dependencies

rasterx requires the following imports which are not included in the go standard library:

  • golang.org/x/image/math/fixed
  • golang.org/x/image/vector

These can be included in your gopath by the following 'get' commands:

  • "go get golang.org/x/image/vector"
  • "go get golang.org/x/image/math/fixed"

If you want to use the freetype style antialiaser, 'go get' or clone into your workspace the scanFT package:

  • github.com/srwiley/scanFT

Documentation

Index

Constants

View Source
const (
	// Number of cubic beziers to approx half a circle
	CubicsPerHalfCircle = 8

	// 1/4 in fixed point
	EpsilonFixed = fixed.Int26_6(16)

	// fixed point t parameterization shift factor;
	// (2^this)/64 is the max length of t for fixed.Int26_6
	TStrokeShift = 14
)
View Source
const MaxDx float32 = math32.Pi / 8

MaxDx is the Maximum radians a cubic splice is allowed to span in ellipse parametric when approximating an off-axis ellipse.

Variables

View Source
var (
	// ButtCap caps lines with a straight line
	ButtCap CapFunc = func(p Adder, a, eNorm fixed.Point26_6) {
		p.Start(a.Add(eNorm))
		p.Line(a.Sub(eNorm))
	}

	// SquareCap caps lines with a square which is slightly longer than ButtCap
	SquareCap CapFunc = func(p Adder, a, eNorm fixed.Point26_6) {
		tpt := a.Add(TurnStarboard90(eNorm))
		p.Start(a.Add(eNorm))
		p.Line(tpt.Add(eNorm))
		p.Line(tpt.Sub(eNorm))
		p.Line(a.Sub(eNorm))
	}

	// RoundCap caps lines with a half-circle
	RoundCap CapFunc = func(p Adder, a, eNorm fixed.Point26_6) {
		GapToCap(p, a, eNorm, RoundGap)
	}

	// CubicCap caps lines with a cubic bezier
	CubicCap CapFunc = func(p Adder, a, eNorm fixed.Point26_6) {
		GapToCap(p, a, eNorm, CubicGap)
	}

	// QuadraticCap caps lines with a quadratic bezier
	QuadraticCap CapFunc = func(p Adder, a, eNorm fixed.Point26_6) {
		GapToCap(p, a, eNorm, QuadraticGap)
	}

	// FlatGap bridges miter-limit gaps with a straight line
	FlatGap GapFunc = func(p Adder, a, tNorm, lNorm fixed.Point26_6) {
		p.Line(a.Add(lNorm))
	}

	// RoundGap bridges miter-limit gaps with a circular arc
	RoundGap GapFunc = func(p Adder, a, tNorm, lNorm fixed.Point26_6) {
		StrokeArc(p, a, a.Add(tNorm), a.Add(lNorm), true, 0, 0, p.Line)
		p.Line(a.Add(lNorm))

	}

	// CubicGap bridges miter-limit gaps with a cubic bezier
	CubicGap GapFunc = func(p Adder, a, tNorm, lNorm fixed.Point26_6) {
		p.CubeBezier(a.Add(tNorm).Add(TurnStarboard90(tNorm)), a.Add(lNorm).Add(TurnPort90(lNorm)), a.Add(lNorm))
	}

	// QuadraticGap bridges miter-limit gaps with a quadratic bezier
	QuadraticGap GapFunc = func(p Adder, a, tNorm, lNorm fixed.Point26_6) {
		c1, c2 := a.Add(tNorm).Add(TurnStarboard90(tNorm)), a.Add(lNorm).Add(TurnPort90(lNorm))
		cm := c1.Add(c2).Mul(fixed.Int26_6(1 << 5))
		p.QuadBezier(cm, a.Add(lNorm))
	}
)

Functions

func AddArc

func AddArc(points []float32, cx, cy, px, py float32, p Adder) (lx, ly float32)

AddArc adds an arc to the adder p

func AddCircle

func AddCircle(cx, cy, r float32, p Adder)

AddCircle adds a circle to the Adder p

func AddEllipse

func AddEllipse(cx, cy, rx, ry, rot float32, p Adder)

AddEllipse adds an elipse with center at cx,cy, with the indicated x and y radius, (rx, ry), rotated around the center by rot degrees.

func AddRect

func AddRect(minX, minY, maxX, maxY, rot float32, p Adder)

AddRect adds a rectangle of the indicated size, rotated around the center by rot degrees.

func AddRoundRect

func AddRoundRect(minX, minY, maxX, maxY, rx, ry, rot float32, gf GapFunc, p Adder)

AddRoundRect adds a rectangle of the indicated size, rotated around the center by rot degrees with rounded corners of radius rx in the x axis and ry in the y axis. gf specifes the shape of the filleting function. Valid values are RoundGap, QuadraticGap, CubicGap, FlatGap, or nil which defaults to a flat gap.

func CalcIntersect

func CalcIntersect(a1, a2, b1, b2 fixed.Point26_6) (x fixed.Point26_6)

CalcIntersect calculates the points of intersection of two fixed point lines and panics if the determinate is zero. You have been warned.

func CircleCircleIntersection

func CircleCircleIntersection(ct, cl fixed.Point26_6, rt, rl fixed.Int26_6) (xt1, xt2 fixed.Point26_6, intersects bool)

CircleCircleIntersection calculates the points of intersection of two circles or returns with intersects == false if no such points exist.

func ClosestPortside

func ClosestPortside(bow, stern, p1, p2 fixed.Point26_6, isIntersecting bool) (xt fixed.Point26_6, intersects bool)

ClosestPortside returns the closest of p1 or p2 on the port side of the line from the bow to the stern. (port means left side of the direction you are heading) isIntersecting is just convienice to reduce code, and if false returns false, because p1 and p2 are not valid

func CubeTo

func CubeTo(ax, ay, bx, by, cx, cy, dx, dy float32, LineTo func(ex, ey float32))

CubeTo flattens the cubic Bezier curve into lines through the LineTo func This functions is adapted from the version found in golang.org/x/image/vector

func DevSquared

func DevSquared(ax, ay, bx, by, cx, cy float32) float32

DevSquared returns a measure of how curvy the sequence (ax, ay) to (bx, by) to (cx, cy) is. It determines how many line segments will approximate a Bézier curve segment. This functions is copied from the version found in golang.org/x/image/vector as are the below comments.

http://lists.nongnu.org/archive/html/freetype-devel/2016-08/msg00080.html gives the rationale for this evenly spaced heuristic instead of a recursive de Casteljau approach:

The reason for the subdivision by n is that I expect the "flatness" computation to be semi-expensive (it's done once rather than on each potential subdivision) and also because you'll often get fewer subdivisions. Taking a circular arc as a simplifying assumption (ie a spherical cow), where I get n, a recursive approach would get 2^⌈lg n⌉, which, if I haven't made any horrible mistakes, is expected to be 33% more in the limit.

func DoCalcCurvature

func DoCalcCurvature(r Raster) bool

DoCalcCurvature determines if calculation of the end curvature is required depending on the raster type and JoinMode

func DotProd

DotProd returns the inner product of p and q

func EllipsePointAt

func EllipsePointAt(a, b, sinTheta, cosTheta, eta, cx, cy float32) (px, py float32)

EllipsePointAt gives points for parameterized ellipse; a, b, radii, eta parameter, center cx, cy

func EllipsePrime

func EllipsePrime(a, b, sinTheta, cosTheta, eta, cx, cy float32) (px, py float32)

EllipsePrime gives tangent vectors for parameterized ellipse; a, b, radii, eta parameter, center cx, cy

func FindEllipseCenter

func FindEllipseCenter(ra, rb *float32, rotX, startX, startY, endX, endY float32, sweep, smallArc bool) (cx, cy float32)

FindEllipseCenter locates the center of the Ellipse if it exists. If it does not exist, the radius values will be increased minimally for a solution to be possible while preserving the ra to rb ratio. ra and rb arguments are pointers that can be checked after the call to see if the values changed. This method uses coordinate transformations to reduce the problem to finding the center of a circle that includes the origin and an arbitrary point. The center of the circle is then transformed back to the original coordinates and returned.

func GapToCap

func GapToCap(p Adder, a, eNorm fixed.Point26_6, gf GapFunc)

GapToCap is a utility that converts a CapFunc to GapFunc

func Invert

func Invert(v fixed.Point26_6) fixed.Point26_6

Invert returns the point inverted around the origin

func Length

func Length(v fixed.Point26_6) fixed.Int26_6

Length is the distance from the origin of the point

func QuadTo

func QuadTo(ax, ay, bx, by, cx, cy float32, LineTo func(dx, dy float32))

QuadTo flattens the quadratic Bezier curve into lines through the LineTo func This functions is adapted from the version found in golang.org/x/image/vector

func RadCurvature

func RadCurvature(p0, p1, p2 fixed.Point26_6, dm fixed.Int52_12) fixed.Int26_6

RadCurvature returns the curvature of a Bezier curve end point, given an end point, the two adjacent control points and the degree. The sign of the value indicates if the center of the osculating circle is left or right (port or starboard) of the curve in the forward direction.

func RayCircleIntersection

func RayCircleIntersection(s1, s2, c fixed.Point26_6, r fixed.Int26_6) (x fixed.Point26_6, intersects bool)

RayCircleIntersection calculates the points of intersection of a ray starting at s2 passing through s1 and a circle in fixed point. Returns intersects == false if no solution is possible. If two solutions are possible, the point closest to s2 is returned

func RayCircleIntersectionF

func RayCircleIntersectionF(s1X, s1Y, s2X, s2Y, cX, cY, r float32) (x, y float32, intersects bool)

RayCircleIntersectionF calculates in floating point the points of intersection of a ray starting at s2 passing through s1 and a circle in fixed point. Returns intersects == false if no solution is possible. If two solutions are possible, the point closest to s2 is returned

func StrokeArc

func StrokeArc(p Adder, a, s1, s2 fixed.Point26_6, clockwise bool, trimStart,
	trimEnd fixed.Int26_6, firstPoint func(p fixed.Point26_6)) (ps1, ds1, ps2, ds2 fixed.Point26_6)

StrokeArc strokes a circular arc by approximation with bezier curves

func ToFixedP

func ToFixedP(x, y float32) (p fixed.Point26_6)

ToFixedP converts two floats to a fixed point.

func ToLength

func ToLength(p fixed.Point26_6, ln fixed.Int26_6) (q fixed.Point26_6)

ToLength scales the point to the length indicated by ln

func TurnPort90

func TurnPort90(v fixed.Point26_6) fixed.Point26_6

TurnPort90 returns the vector 90 degrees port (left in direction heading)

func TurnStarboard90

func TurnStarboard90(v fixed.Point26_6) fixed.Point26_6

TurnStarboard90 returns the vector 90 degrees starboard (right in direction heading)

Types

type Adder

type Adder interface {
	// Start starts a new curve at the given point.
	Start(a fixed.Point26_6)

	// Line adds a line segment to the path
	Line(b fixed.Point26_6)

	// QuadBezier adds a quadratic bezier curve to the path
	QuadBezier(b, c fixed.Point26_6)

	// CubeBezier adds a cubic bezier curve to the path
	CubeBezier(b, c, d fixed.Point26_6)

	// Closes the path to the start point if closeLoop is true
	Stop(closeLoop bool)
}

Adder is the interface for types that can accumulate path commands

type C2Point

type C2Point struct {
	P, TTan, LTan, TNorm, LNorm fixed.Point26_6
	RT, RL                      fixed.Int26_6
}

C2Point represents a point that connects two stroke segments and holds the tangent, normal and radius of curvature of the trailing and leading segments in fixed point values.

func (*C2Point) BlackWidowMark

func (jp *C2Point) BlackWidowMark(ra Adder)

BlackWidowMark handles a gap in a stroke that can occur when a line end is too close to a segment to segment join point. Although it is only required in those cases, at this point, no code has been written to properly detect when it is needed, so for now it just draws by default.

type CapFunc

type CapFunc func(p Adder, a, eNorm fixed.Point26_6)

CapFunc defines a function that draws caps on the ends of lines

type Dasher

type Dasher struct {
	Stroker
	Dashes         []fixed.Int26_6
	DashPlace      int
	FirstDashIsGap bool
	DashIsGap      bool
	DeltaDash      fixed.Int26_6
	DashOffset     fixed.Int26_6

	// Sgm allows us to switch between dashing
	// and non-dashing rasterizers in the SetStroke function.
	Sgm Raster
}

Dasher struct extends the Stroker and can draw dashed lines with end capping

func NewDasher

func NewDasher(width, height int, scanner Scanner) *Dasher

NewDasher returns a Dasher ptr with default values. A Dasher has all of the capabilities of a Stroker, Filler, and Scanner, plus the ability to stroke curves with solid lines. Use SetStroke to configure with non-default values.

func (*Dasher) CubeBezier

func (r *Dasher) CubeBezier(b, c, d fixed.Point26_6)

CubeBezier starts a stroked cubic bezier. It is a low level function exposed for the purposes of callbacks and debugging.

func (*Dasher) DashLineStrokeBit

func (r *Dasher) DashLineStrokeBit(b, bnorm fixed.Point26_6, dontClose bool)

DashLineStrokeBit is a helper function that reduces code redundancy in the LineF function.

func (*Dasher) JoinF

func (r *Dasher) JoinF()

JoinF overides stroker JoinF during dashed stroking, because we need to slightly modify the the call as below to handle the case of the join being in a dash gap.

func (*Dasher) Line

func (r *Dasher) Line(b fixed.Point26_6)

Line for Dasher is here to pass the dasher sgm to LineP

func (*Dasher) LineF

func (r *Dasher) LineF(b fixed.Point26_6)

LineF overides stroker LineF to modify the the call as below while performing the join in a dashed stroke.

func (*Dasher) QuadBezier

func (r *Dasher) QuadBezier(b, c fixed.Point26_6)

QuadBezier for dashing

func (*Dasher) SetStroke

func (r *Dasher) SetStroke(width, miterLimit fixed.Int26_6, capL, capT CapFunc, gp GapFunc, jm JoinMode, dashes []float32, dashOffset float32)

SetStroke set the parameters for stroking a line. width is the width of the line, miterlimit is the miter cutoff value for miter, arc, miterclip and arcClip joinModes. CapL and CapT are the capping functions for leading and trailing line ends. If one is nil, the other function is used at both ends. gp is the gap function that determines how a gap on the convex side of two lines joining is filled. jm is the JoinMode for curve segments. Dashes is the values for the dash pattern. Pass in nil or an empty slice for no dashes. dashoffset is the starting offset into the dash array.

func (*Dasher) Start

func (r *Dasher) Start(a fixed.Point26_6)

Start starts a dashed line

func (*Dasher) Stop

func (r *Dasher) Stop(isClosed bool)

Stop terminates a dashed line

type Filler

type Filler struct {
	Scanner
	A     fixed.Point26_6
	First fixed.Point26_6
}

Filler is a filler that implements Raster.

func NewFiller

func NewFiller(width, height int, scanner Scanner) *Filler

NewFiller returns a Filler ptr with default values. A Filler in addition to rasterizing lines like a Scann, can also rasterize quadratic and cubic bezier curves. If Scanner is nil default scanner ScannerGV is used

func (*Filler) Clear

func (r *Filler) Clear()

Clear resets the filler

func (*Filler) CubeBezier

func (r *Filler) CubeBezier(b, c, d fixed.Point26_6)

CubeBezier adds a cubic bezier to the curve

func (*Filler) CubeBezierF

func (r *Filler) CubeBezierF(sgm Raster, b, c, d fixed.Point26_6)

CubeBezierF adds a cubic bezier to the curve. sending the line calls the the sgm Rasterizer

func (*Filler) JoinF

func (r *Filler) JoinF()

JoinF is a no-op for a filling rasterizer. This is used in stroking and dashed stroking

func (*Filler) Line

func (r *Filler) Line(b fixed.Point26_6)

Line for a filling rasterizer is just the line call in scan

func (*Filler) LineF

func (r *Filler) LineF(b fixed.Point26_6)

LineF for a filling rasterizer is just the line call in scan

func (*Filler) QuadBezier

func (r *Filler) QuadBezier(b, c fixed.Point26_6)

QuadBezier adds a quadratic segment to the current curve.

func (*Filler) QuadBezierF

func (r *Filler) QuadBezierF(sgm Raster, b, c fixed.Point26_6)

QuadBezierF adds a quadratic segment to the sgm Rasterizer.

func (*Filler) SetBounds

func (r *Filler) SetBounds(width, height int)

SetBounds sets the maximum width and height of the rasterized image and calls Clear. The width and height are in pixels, not fixed.Int26_6 units.

func (*Filler) Start

func (r *Filler) Start(a fixed.Point26_6)

Start starts a new path at the given point.

func (*Filler) Stop

func (r *Filler) Stop(isClosed bool)

Stop sends a path at the given point.

type GapFunc

type GapFunc func(p Adder, a, tNorm, lNorm fixed.Point26_6)

GapFunc defines a function to bridge gaps when the miter limit is exceeded

type JoinMode

type JoinMode int32 //enums:enum

JoinMode type to specify how segments join.

const (
	Arc JoinMode = iota
	ArcClip
	Miter
	MiterClip
	Bevel
	Round
)

JoinMode constants determine how stroke segments bridge the gap at a join ArcClip mode is like MiterClip applied to arcs, and is not part of the SVG2.0 standard.

const JoinModeN JoinMode = 6

JoinModeN is the highest valid value for type JoinMode, plus one.

func JoinModeValues

func JoinModeValues() []JoinMode

JoinModeValues returns all possible values for the type JoinMode.

func (JoinMode) Desc

func (i JoinMode) Desc() string

Desc returns the description of the JoinMode value.

func (JoinMode) Int64

func (i JoinMode) Int64() int64

Int64 returns the JoinMode value as an int64.

func (JoinMode) MarshalText

func (i JoinMode) MarshalText() ([]byte, error)

MarshalText implements the encoding.TextMarshaler interface.

func (*JoinMode) SetInt64

func (i *JoinMode) SetInt64(in int64)

SetInt64 sets the JoinMode value from an int64.

func (*JoinMode) SetString

func (i *JoinMode) SetString(s string) error

SetString sets the JoinMode value from its string representation, and returns an error if the string is invalid.

func (JoinMode) String

func (i JoinMode) String() string

String returns the string representation of this JoinMode value.

func (*JoinMode) UnmarshalText

func (i *JoinMode) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface.

func (JoinMode) Values

func (i JoinMode) Values() []enums.Enum

Values returns all possible values for the type JoinMode.

type MatrixAdder

type MatrixAdder struct {
	Adder
	M math32.Matrix2
}

MatrixAdder is an adder that applies matrix M to all points

func (*MatrixAdder) CubeBezier

func (t *MatrixAdder) CubeBezier(b, c, d fixed.Point26_6)

CubeBezier adds a cubic segment to the current curve.

func (*MatrixAdder) Line

func (t *MatrixAdder) Line(b fixed.Point26_6)

Line adds a linear segment to the current curve.

func (*MatrixAdder) QuadBezier

func (t *MatrixAdder) QuadBezier(b, c fixed.Point26_6)

QuadBezier adds a quadratic segment to the current curve.

func (*MatrixAdder) Reset

func (t *MatrixAdder) Reset()

Reset sets the matrix M to identity

func (*MatrixAdder) Start

func (t *MatrixAdder) Start(a fixed.Point26_6)

Start starts a new path

type Path

type Path []fixed.Int26_6

A Path starts with a PathCommand value followed by zero to three fixed int points.

func (Path) AddTo

func (p Path) AddTo(q Adder)

AddTo adds the Path p to q.

func (*Path) Clear

func (p *Path) Clear()

Clear zeros the path slice

func (*Path) CubeBezier

func (p *Path) CubeBezier(b, c, d fixed.Point26_6)

CubeBezier adds a cubic segment to the current curve.

func (*Path) Line

func (p *Path) Line(b fixed.Point26_6)

Line adds a linear segment to the current curve.

func (*Path) QuadBezier

func (p *Path) QuadBezier(b, c fixed.Point26_6)

QuadBezier adds a quadratic segment to the current curve.

func (*Path) Start

func (p *Path) Start(a fixed.Point26_6)

Start starts a new curve at the given point.

func (*Path) Stop

func (p *Path) Stop(closeLoop bool)

Stop joins the ends of the path

func (Path) String

func (p Path) String() string

String returns a readable representation of a Path.

func (Path) ToSVGPath

func (p Path) ToSVGPath() string

ToSVGPath returns a string representation of the path

type PathCommand

type PathCommand fixed.Int26_6 //enums:enum -no-extend

PathCommand is the type for the path command token

const (
	PathMoveTo PathCommand = iota
	PathLineTo
	PathQuadTo
	PathCubicTo
	PathClose
)

Human readable path command constants

const PathCommandN PathCommand = 5

PathCommandN is the highest valid value for type PathCommand, plus one.

func PathCommandValues

func PathCommandValues() []PathCommand

PathCommandValues returns all possible values for the type PathCommand.

func (PathCommand) Desc

func (i PathCommand) Desc() string

Desc returns the description of the PathCommand value.

func (PathCommand) Int64

func (i PathCommand) Int64() int64

Int64 returns the PathCommand value as an int64.

func (PathCommand) MarshalText

func (i PathCommand) MarshalText() ([]byte, error)

MarshalText implements the encoding.TextMarshaler interface.

func (*PathCommand) SetInt64

func (i *PathCommand) SetInt64(in int64)

SetInt64 sets the PathCommand value from an int64.

func (*PathCommand) SetString

func (i *PathCommand) SetString(s string) error

SetString sets the PathCommand value from its string representation, and returns an error if the string is invalid.

func (PathCommand) String

func (i PathCommand) String() string

String returns the string representation of this PathCommand value.

func (*PathCommand) UnmarshalText

func (i *PathCommand) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface.

func (PathCommand) Values

func (i PathCommand) Values() []enums.Enum

Values returns all possible values for the type PathCommand.

type Raster

type Raster interface {
	Adder
	LineF(b fixed.Point26_6)
	JoinF()
}

Raster is the interface for rasterizer types. It extends the Adder interface to include LineF and JoinF functions.

type Scanner

type Scanner interface {
	Start(a fixed.Point26_6)
	Line(b fixed.Point26_6)
	Draw()
	GetPathExtent() fixed.Rectangle26_6
	SetBounds(w, h int)

	// SetColor sets the color used for rendering.
	SetColor(color image.Image)

	SetWinding(useNonZeroWinding bool)
	Clear()

	// SetClip sets an optional clipping rectangle to restrict rendering only to
	// that region. If rect is zero (image.Rectangle{}), then clipping is disabled.
	SetClip(rect image.Rectangle)
}

Scanner is the interface for path generating types

type Stroker

type Stroker struct {
	Filler

	// Trailing cap function
	CapT CapFunc

	// Leading cpa function
	CapL CapFunc

	// When gap appears between segments, this function is called
	JoinGap GapFunc

	// Tracks progress of the stroke
	FirstP C2Point

	// Tracks progress of the stroke
	TrailPoint C2Point

	// Tracks progress of the stroke
	LeadPoint C2Point

	// last normal of intra-seg connection.
	Ln fixed.Point26_6

	// U is the half-width of the stroke.
	U fixed.Int26_6

	MLimit fixed.Int26_6

	JoinMode JoinMode

	InStroke bool
}

Stroker does everything a Filler does, but also allows for stroking and dashed stroking in addition to filling

func NewStroker

func NewStroker(width, height int, scanner Scanner) *Stroker

NewStroker returns a ptr to a Stroker with default values. A Stroker has all of the capabilities of a Filler and Scanner, plus the ability to stroke curves with solid lines. Use SetStroke to configure with non-default values.

func (*Stroker) CalcEndCurvature

func (r *Stroker) CalcEndCurvature(p0, p1, p2, q0, q1, q2 fixed.Point26_6,
	dm fixed.Int52_12, calcRadCuve bool)

CalcEndCurvature calculates the radius of curvature given the control points of a bezier curve. It is a low level function exposed for the purposes of callbacks and debugging.

func (*Stroker) CubeBezier

func (r *Stroker) CubeBezier(b, c, d fixed.Point26_6)

CubeBezier starts a stroked quadratic bezier.

func (*Stroker) CubeBezierf

func (r *Stroker) CubeBezierf(sgm Raster, b, c, d fixed.Point26_6)

func (*Stroker) JoinF

func (r *Stroker) JoinF()

func (*Stroker) Joiner

func (r *Stroker) Joiner(p C2Point)

Joiner is called when two segments of a stroke are joined. it is exposed so that if can be wrapped to generate callbacks for the join points.

func (*Stroker) Line

func (r *Stroker) Line(b fixed.Point26_6)

Line adds a line segment to the rasterizer

func (*Stroker) LineF

func (r *Stroker) LineF(b fixed.Point26_6)

LineF is for intra-curve lines. It is required for the Rasterizer interface so that if the line is being stroked or dash stroked, different actions can be taken.

func (*Stroker) LineSeg

func (r *Stroker) LineSeg(sgm Raster, b fixed.Point26_6)

LineSeg is called by both the Stroker and Dasher

func (*Stroker) QuadBezier

func (r *Stroker) QuadBezier(b, c fixed.Point26_6)

QuadBezier starts a stroked quadratic bezier.

func (*Stroker) QuadBezierf

func (r *Stroker) QuadBezierf(s Raster, b, c fixed.Point26_6)

QuadBezierf calcs end curvature of beziers

func (*Stroker) SetStroke

func (r *Stroker) SetStroke(width, miterLimit fixed.Int26_6, capL, capT CapFunc, gp GapFunc, jm JoinMode)

SetStroke set the parameters for stroking a line. width is the width of the line, miterlimit is the miter cutoff value for miter, arc, miterclip and arcClip joinModes. CapL and CapT are the capping functions for leading and trailing line ends. If one is nil, the other function is used at both ends. If both are nil, both ends are ButtCapped. gp is the gap function that determines how a gap on the convex side of two joining lines is filled. jm is the JoinMode for curve segments.

func (*Stroker) Start

func (r *Stroker) Start(a fixed.Point26_6)

Start iniitates a stroked path

func (*Stroker) Stop

func (r *Stroker) Stop(isClosed bool)

Stop a stroked line. The line will close is isClosed is true. Otherwise end caps will be drawn at both ends.

func (*Stroker) StrokeEdge

func (r *Stroker) StrokeEdge(p C2Point, crossProd fixed.Int26_6)

StrokeEdge reduces code redundancy in the Joiner function by 2x since it handles the top and bottom edges. This function encodes most of the logic of how to handle joins between the given C2Point point p, and the end of the line.

Jump to

Keyboard shortcuts

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