forked from Cloudxtreme/lavabot
-
Notifications
You must be signed in to change notification settings - Fork 2
/
sigil.go
94 lines (81 loc) · 2.17 KB
/
sigil.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package gen
import (
"fmt"
"image"
"image/color"
"io"
"github.com/ajstarks/svgo"
)
type Sigil struct {
Rows int
Foreground []color.NRGBA
Background color.NRGBA
}
func (s *Sigil) Make(width int, inverted bool, data []byte) image.Image {
fg, bg := s.colors(data[0], inverted)
palette := color.Palette{bg, fg}
img := image.NewPaletted(image.Rect(0, 0, width, width), palette)
for _, rect := range s.cells(width, data[1:]) {
for x := rect.Min.X; x < rect.Max.X; x++ {
for y := rect.Min.Y; y < rect.Max.Y; y++ {
img.Pix[y*img.Stride+x] = 1
}
}
}
return img
}
func (s *Sigil) MakeSVG(w io.Writer, width int, inverted bool, data []byte) {
canvas := svg.New(w)
fg, bg := s.colors(data[0], inverted)
fgFill, bgFill := svgFill(fg), svgFill(bg)
canvas.Start(width, width)
canvas.Rect(0, 0, width, width, bgFill)
for _, rect := range s.cells(width, data[1:]) {
canvas.Rect(rect.Min.X, rect.Min.Y, rect.Dx(), rect.Dy(), fgFill)
}
canvas.End()
}
func svgFill(c color.NRGBA) string {
return fmt.Sprintf("fill:rgba(%d,%d,%d,%.2g);", c.R, c.G, c.B, float64(c.A)*1/255)
}
func (s *Sigil) fill(cell int, data []byte) bool {
if data[cell/8]>>uint(8-((cell%8)+1))&1 == 0 {
return false
}
return true
}
func (s *Sigil) cells(width int, data []byte) []image.Rectangle {
width = width / (s.Rows + 1)
cols := s.Rows/2 + s.Rows%2
cells := cols * s.Rows
res := make([]image.Rectangle, 0, s.Rows*s.Rows)
padding := width / 2
for i := 0; i < cells; i++ {
if !s.fill(i, data) {
continue
}
column := i / s.Rows
row := i % s.Rows
pt := image.Pt(padding+(column*width), padding+(row*width))
rect := image.Rectangle{pt, image.Pt(pt.X+width, pt.Y+width)}
if s.Rows%2 == 0 && column == cols-1 {
// last/middle column, double width
rect.Max.X += width
}
res = append(res, rect)
if column < cols-1 {
// add mirrored column
rect.Min.X = padding + ((s.Rows - column - 1) * width)
rect.Max.X = rect.Min.X + width
res = append(res, rect)
}
}
return res
}
func (s *Sigil) colors(b byte, inverted bool) (color.NRGBA, color.NRGBA) {
fg := s.Foreground[int(b)%len(s.Foreground)]
if inverted {
return s.Background, fg
}
return fg, s.Background
}