// Package pattern defines a pattern that can be drawn to a canvas. package pattern import ( "fmt" "git.wtrh.nl/wouter/gopatterns/pkg/pattern/point" "git.wtrh.nl/wouter/gopatterns/pkg/pattern/text" "github.com/tdewolff/canvas" "golang.org/x/image/font/gofont/goregular" "gopkg.in/Knetic/govaluate.v3" ) // Pattern contains all the points, lines and dimensions to draw a pattern to a canvas. type Pattern struct { points map[point.ID]point.Point lines []pathDrawer dimensions Dimensions texts []*text.Text } type pathDrawer interface { Draw(c *canvas.Canvas) error } // AddPoint adds a point.Point to the pattern. func (p *Pattern) AddPoint(point point.Point) { p.points[point.ID()] = point } // AddLine adds a drawable line to the pattern. func (p *Pattern) AddLine(line pathDrawer) { p.lines = append(p.lines, line) } // GetPoints returns a slice with points for the given IDs. func (p *Pattern) GetPoints(id ...point.ID) []point.Point { points := make([]point.Point, 0, len(id)) for _, i := range id { points = append(points, p.GetPoint(i)) } return points } // GetPoint returns the point for the given ID. func (p *Pattern) GetPoint(id point.ID) point.Point { //nolint:ireturn return p.points[id] } // NewPattern returns a new Pattern. func NewPattern() *Pattern { return &Pattern{ points: make(map[point.ID]point.Point, 32), lines: make([]pathDrawer, 0, 32), dimensions: make(Dimensions), texts: make([]*text.Text, 0), } } // ToCanvas draws the pattern on the provided [canvas.Canvas]. func (p *Pattern) ToCanvas(c *canvas.Canvas) error { fontDejaVu := canvas.NewFontFamily("latin") if err := fontDejaVu.LoadFont(goregular.TTF, 0, canvas.FontRegular); err != nil { panic(err) } face := fontDejaVu.Face(12.0, canvas.Black, canvas.FontRegular) for _, pp := range p.points { point.Draw(c, pp, face) } for _, path := range p.lines { err := path.Draw(c) if err != nil { return fmt.Errorf("draw path to canvas: %w", err) } } for _, t := range p.texts { t.ToCanvas(c, face) } return nil } // Parameters return the parameters based on the dimensions. func (p *Pattern) Parameters() govaluate.MapParameters { return p.dimensions.Parameters() } func (p *Pattern) AddText(t *text.Text) { p.texts = append(p.texts, t) } func (p *Pattern) SetDimensions(dimensions Dimensions) { p.dimensions = dimensions }