sfntshape

package module
v0.0.0-...-70e7ea1 Latest Latest
Warning

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

Go to latest
Published: Aug 23, 2025 License: MIT Imports: 7 Imported by: 3

README

sfntshape

Go Reference

A simple Shape type to render vectorial shapes through golang.org/x/image/vector#Rasterizer.

The Shape type offers two APIs:

  • sfnt/Ebitengine style: MoveTo, LineTo, QuadTo, CubeTo.
  • Relative style: Turn, TurnTo, Move, Line.

This code was originally part of etxt, but it was split after v0.0.9. The code now doesn't depend on etxt nor Ebitengine.

Check out a cool online example, or run it yourself with:

go run github.com/tinne26/sfntshape/examples/rng@latest

(Instructions can be hidden with H and fullscreen can be switched with F)

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Rasterize

func Rasterize(outline sfnt.Segments, rasterizer *vector.Rasterizer, originX, originY Fract) (*image.Alpha, error)

Rasterize an outline into a single-channel image.

Types

type Fract

type Fract = fixed.Int26_6

Provided for better compatibility with the etxt/fract.Unit type.

type Shape

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

A helper type to assist the creation of shapes that can later be converted to sfnt.Segments and rasterized with Rasterize(), or directly converted to an *image.RGBA.

Notice that the rasterization is a CPU process, so working with big shapes (based on their bounding rectangle) can be quite expensive.

Despite what the names of the methods might lead you to believe, shapes are not created by "drawing lines", but rather by defining a set of boundaries that enclose an area. If you get unexpected results using shapes, come back to think about this.

Shapes by themselves do not care about the direction you use to define the segments (clockwise/counter-clockwise), but rasterizers that use the segments most often do. For example, if you define two squares one inside the other, both in the same order (e.g: top-left to top-right, top-right to bottom right...) the rasterized result will be a single square. If you define them following opposite directions, instead, the result will be the difference between the two squares.

func New

func New() Shape

Creates a new Shape object.

func (*Shape) CubeTo

func (shape *Shape) CubeTo(cx1, cy1, cx2, cy2, x, y int)

Creates a cubic Bézier curve to (x, y) with (cx1, cy1) and (cx2, cy2) as the control points. See golang.org/x/image/vector.Rasterizer operations and golang.org/x/image/font/sfnt.Segment.

func (*Shape) CubeToFract

func (shape *Shape) CubeToFract(cx1, cy1, cx2, cy2, x, y Fract)

Like Shape.CubeTo, but with fractional coordinates.

func (*Shape) Direction

func (shape *Shape) Direction() float64

Direction returns the direction at the end of the last segment, in radians. The directions match Golang's conventions:

  • 0: x axis positive (right)
  • math.Pi/2: y axis positive (up by default)
  • math.Pi: x axis negative (left)
  • 3*math.Pi/2: y axis negative (down by default)

func (*Shape) FindFurthest

func (shape *Shape) FindFurthest(ox, oy Fract) (x, y Fract)

FindFurthest finds the furthest point in the shape from the given position.

func (*Shape) GetScale

func (shape *Shape) GetScale() Fract

Returns the current scaling factor.

func (*Shape) HasInvertY

func (shape *Shape) HasInvertY() bool

Returns whether Shape.InvertY is active or inactive.

func (*Shape) InvertY

func (shape *Shape) InvertY(active bool)

InvertY changes the positive Y axis from going up to going down when enabled.

Let's say you want to draw a triangle pointing up, similar to an "A". By default, you would move to (0, 0) and then draw lines to (k, 2*k), (2*k, 0) and back to (0, 0).

If you set InvertY to true, the previous shape will draw a triangle pointing down instead, similar to a "V". This is a convenient flag that makes it easier to work on different contexts (e.g., font glyphs are defined with the ascenders going into the negative y plane).

InvertY can also be used creatively or to switch between clockwise and counter-clockwise directions when drawing symmetrical shapes that have their center at (0, 0).

func (*Shape) Line

func (shape *Shape) Line(d int)

Line creates a straight boundary from the current position to d units in the current direction.

func (*Shape) LineFract

func (shape *Shape) LineFract(d Fract)

LineFract creates a straight boundary from the current position to d units in the current direction.

func (*Shape) LineTo

func (shape *Shape) LineTo(x, y int)

Creates a straight boundary from the current position to (x, y). See vector.Rasterizer operations and sfnt.Segment.

func (*Shape) LineToFract

func (shape *Shape) LineToFract(x, y Fract)

Like Shape.LineTo, but with fractional coordinates.

func (*Shape) Move

func (shape *Shape) Move(d int)

Move moves d units in the current direction.

func (*Shape) MoveFract

func (shape *Shape) MoveFract(d Fract)

Move moves d units in the current direction.

func (*Shape) MoveTo

func (shape *Shape) MoveTo(x, y int)

Moves the current position to (x, y). See vector.Rasterizer operations and sfnt.Segment.

func (*Shape) MoveToFract

func (shape *Shape) MoveToFract(x, y Fract)

Like Shape.MoveTo, but with fractional coordinates.

func (*Shape) Paint

func (shape *Shape) Paint(drawColor, backColor color.Color) *image.RGBA

A helper method to rasterize the current shape with the given colors. You could then export the result to a png file, e.g.:

file, _ := os.Create("my_ugly_shape.png")
_ = png.Encode(file, shape.Paint(color.White, color.Black))
// ...maybe even checking errors and closing the file ;)

func (*Shape) Position

func (shape *Shape) Position() (x, y Fract)

Position returns the current position.

func (*Shape) QuadTo

func (shape *Shape) QuadTo(ctrlX, ctrlY, x, y int)

Creates a quadratic Bézier curve (also known as a conic Bézier curve) to (x, y) with (ctrlX, ctrlY) as the control point. See vector.Rasterizer operations and sfnt.Segment.

func (*Shape) QuadToFract

func (shape *Shape) QuadToFract(ctrlX, ctrlY, x, y Fract)

Like Shape.QuadTo, but with fractional coordinates.

func (*Shape) Rasterize

func (shape *Shape) Rasterize() (*image.Alpha, error)

A helper method to rasterize the current shape into an *image.Alpha.

func (*Shape) RasterizeFract

func (shape *Shape) RasterizeFract(offsetX, offsetY Fract) (*image.Alpha, error)

A helper method to rasterize the current shape displaced by the given fractional offset into an *image.Alpha.

func (*Shape) Reset

func (shape *Shape) Reset()

Resets the shape segments. Be careful to not be holding the segments from Shape.Segments() when calling this (they may be overriden soon).

func (*Shape) Segments

func (shape *Shape) Segments() sfnt.Segments

Gets the shape information as sfnt.Segments. The underlying data is referenced both by the Shape and the sfnt.Segments, so be careful what you do with it.

func (*Shape) SetScale

func (shape *Shape) SetScale(scale float64)

Sets a scaling factor to be applied to the coordinates of subsequent Shape.MoveTo(), Shape.LineTo() and similar commands.

func (*Shape) SetScaleFract

func (shape *Shape) SetScaleFract(scale Fract)

Like Shape.SetScale(), but expecting a Fract value instead of a float64.

func (*Shape) Turn

func (shape *Shape) Turn(degrees float64)

Turn changes the current direction by the given degrees. Positive values turn right, negative values turn left.

func (*Shape) TurnTo

func (shape *Shape) TurnTo(degrees float64)

Directories

Path Synopsis
examples
rng module

Jump to

Keyboard shortcuts

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