您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

108 行
2.7KB

  1. // Package pattern defines a pattern that can be drawn to a canvas.
  2. package pattern
  3. import (
  4. "fmt"
  5. "git.wtrh.nl/patterns/gopatterns/pkg/dimensions"
  6. "git.wtrh.nl/patterns/gopatterns/pkg/pattern/text"
  7. "git.wtrh.nl/patterns/gopatterns/pkg/point"
  8. "git.wtrh.nl/patterns/gopatterns/pkg/util"
  9. "github.com/tdewolff/canvas"
  10. "golang.org/x/image/font/gofont/goregular"
  11. "gopkg.in/Knetic/govaluate.v3"
  12. )
  13. // The Pattern contains all the points, lines and dimensions to draw a pattern to a canvas.
  14. type Pattern struct {
  15. points map[util.ID]point.Point
  16. lines []pathDrawer
  17. dimensions dimensions.Dimensions
  18. texts []*text.Text
  19. }
  20. type pathDrawer interface {
  21. Length() (float64, error)
  22. Draw(c *canvas.Canvas) error
  23. }
  24. // AddPoint adds a point.Point to the pattern.
  25. func (p *Pattern) AddPoint(point point.Point) {
  26. p.points[point.ID()] = point
  27. }
  28. // AddLine adds a drawable line to the pattern.
  29. func (p *Pattern) AddLine(line pathDrawer) {
  30. p.lines = append(p.lines, line)
  31. }
  32. // GetPoints returns a slice with points for the given IDs.
  33. func (p *Pattern) GetPoints(id []util.ID) []point.Point {
  34. points := make([]point.Point, 0, len(id))
  35. for _, i := range id {
  36. points = append(points, p.GetPoint(i))
  37. }
  38. return points
  39. }
  40. // GetPoint returns the point for the given ID.
  41. func (p *Pattern) GetPoint(id util.ID) point.Point { //nolint:ireturn
  42. return p.points[id]
  43. }
  44. // NewPattern returns a new Pattern.
  45. func NewPattern() *Pattern {
  46. return &Pattern{
  47. points: make(map[util.ID]point.Point, 32),
  48. lines: make([]pathDrawer, 0, 32),
  49. dimensions: make(dimensions.Dimensions),
  50. texts: make([]*text.Text, 0),
  51. }
  52. }
  53. // ToCanvas draws the pattern on the provided [canvas.Canvas].
  54. func (p *Pattern) ToCanvas(c *canvas.Canvas, debug bool) error {
  55. fontDejaVu := canvas.NewFontFamily("latin")
  56. if err := fontDejaVu.LoadFont(goregular.TTF, 0, canvas.FontRegular); err != nil {
  57. panic(err)
  58. }
  59. face := fontDejaVu.Face(12.0, canvas.Black, canvas.FontRegular)
  60. for _, pp := range p.points {
  61. point.Draw(c, pp, face, debug)
  62. }
  63. for _, path := range p.lines {
  64. err := path.Draw(c)
  65. if err != nil {
  66. return fmt.Errorf("draw path to canvas: %w", err)
  67. }
  68. }
  69. for _, t := range p.texts {
  70. t.ToCanvas(c, face)
  71. }
  72. return nil
  73. }
  74. // Parameters return the parameters based on the dimensions.
  75. func (p *Pattern) Parameters() govaluate.MapParameters {
  76. return p.dimensions.Parameters()
  77. }
  78. func (p *Pattern) AddText(t *text.Text) {
  79. p.texts = append(p.texts, t)
  80. }
  81. func (p *Pattern) SetDimensions(dimensions dimensions.Dimensions) {
  82. p.dimensions = dimensions
  83. }
  84. // AddDimension adds a dimension to a pattern.
  85. func (p *Pattern) AddDimension(id dimensions.DimensionID, dimension dimensions.Dimension) {
  86. p.dimensions[id] = dimension
  87. }