-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsvg.go
82 lines (70 loc) · 2.01 KB
/
svg.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
package favicon
import (
"bytes"
"github.com/mrmelon54/png2ico"
_ "embed"
"github.com/tdewolff/canvas"
"github.com/tdewolff/canvas/renderers"
"github.com/tdewolff/canvas/renderers/svg"
"image/color"
"strings"
)
//go:embed Lato-Bold.ttf
var latoBold []byte
type Svg struct {
c *canvas.Canvas
color int
letter rune
}
func NewSvg(addr string, faviconColor *Color) *Svg {
return &Svg{canvas.New(96, 96), faviconColor.PickColor(addr), []rune(strings.ToUpper(addr))[0]}
}
func (favicon *Svg) generate() {
favicon.c.Reset()
ctx := canvas.NewContext(favicon.c)
round := canvas.RoundedRectangle(96, 96, 8)
ctx.SetFillColor(color.RGBA{R: favicon.getR(), G: favicon.getG(), B: favicon.getB(), A: 0xff})
ctx.DrawPath(0, 0, round)
fontFamily := canvas.NewFontFamily("Lato")
if err := fontFamily.LoadFont(latoBold, 0, canvas.FontBold); err != nil {
panic(err)
}
face := fontFamily.Face(100, canvas.White, canvas.FontBold, canvas.FontNormal)
fontPath, _, err := face.ToPath(string(favicon.letter))
if err != nil {
panic(err)
}
ctx.SetFillColor(color.White)
ctx.Translate(16, -10)
ctx.Rotate(10)
ctx.Scale(3.6, 3.6)
ctx.DrawPath(0, 0, fontPath)
}
func (favicon *Svg) getR() uint8 { return uint8(favicon.color >> 16) }
func (favicon *Svg) getG() uint8 { return uint8(favicon.color >> 8) }
func (favicon *Svg) getB() uint8 { return uint8(favicon.color) }
func (favicon *Svg) ProduceSvg() ([]byte, error) {
favicon.generate()
b := new(bytes.Buffer)
err := renderers.SVG(&svg.Options{EmbedFonts: false, SubsetFonts: false, ImageEncoding: canvas.Lossless})(b, favicon.c)
if err != nil {
return nil, err
}
return b.Bytes(), nil
}
func (favicon *Svg) ProducePng() ([]byte, error) {
favicon.generate()
b := new(bytes.Buffer)
err := renderers.PNG()(b, favicon.c)
if err != nil {
return nil, err
}
return b.Bytes(), nil
}
func (favicon *Svg) ProduceIco() ([]byte, error) {
b, err := favicon.ProducePng()
if err != nil {
return nil, err
}
return png2ico.ConvertPngToIco(b, int(favicon.c.W), int(favicon.c.H))
}