@@ -13,11 +13,13 @@ import (
1313type Options int
1414
1515const (
16- cacheTTL = 30 * 24 * time .Hour // 1 month
17- contentType = "image/png"
16+ cacheTTL = 30 * 24 * time .Hour // 1 month
17+ contentTypePNG = "image/png"
1818
19- // GreyBackground is an option to force a grey background
2019 GreyBackground Options = 1 + iota
20+ Translucent Options = 1 + iota
21+ FormatPNG Options = 1 + iota // If this option is absent, SVG is assumed
22+ EmbedFont Options = 1 + iota
2123)
2224
2325// Initials is able to generate initial avatar.
@@ -41,21 +43,38 @@ func NewService(cache cache.Cache, cmd string) *Service {
4143
4244// GenerateInitials an image with the initials for the given name (and the
4345// content-type to use for the HTTP response).
44- func (s * Service ) GenerateInitials (publicName string , opts ... Options ) ([]byte , string , error ) {
45- name := strings .TrimSpace (publicName )
46- info := extractInfo ( name )
46+ func (s * Service ) GenerateInitials (publicName string , fontLoader avatarFontProvider , opts ... Options ) ([]byte , string , error ) {
47+ info := extractInfo ( strings .TrimSpace (publicName ) )
48+ isPNG , isGrayscale , isTranslucent , embedFont := false , false , false , false
4749 for _ , opt := range opts {
4850 if opt == GreyBackground {
4951 info .color = charcoalGrey
52+ isGrayscale = true
53+ } else if opt == Translucent {
54+ isTranslucent = true
55+ } else if opt == FormatPNG {
56+ isPNG = true
57+ } else if opt == EmbedFont {
58+ embedFont = true
5059 }
5160 }
5261
53- key := "initials:" + info .initials + info .color
62+ if ! embedFont {
63+ fontLoader = nil
64+ }
65+ if ! isPNG {
66+ return SvgForAvatar (info .initials , uint (info .colorHash ), isGrayscale , isTranslucent , fontLoader )
67+ }
68+ initials := info .initials
69+ if initials == "" {
70+ initials = "?"
71+ }
72+ key := "initials:" + initials + info .color
5473 if bytes , ok := s .cache .Get (key ); ok {
55- return bytes , contentType , nil
74+ return bytes , contentTypePNG , nil
5675 }
5776
58- bytes , err := s .initials .Generate (info . initials , info .color )
77+ bytes , err := s .initials .Generate (initials , info .color )
5978 if err != nil {
6079 return nil , "" , err
6180 }
@@ -87,14 +106,16 @@ var colors = []string{
87106var charcoalGrey = "#32363F"
88107
89108type info struct {
90- initials string
91- color string
109+ initials string
110+ colorHash int
111+ color string
92112}
93113
94114func extractInfo (name string ) info {
95115 initials := strings .ToUpper (getInitials (name ))
96- color := getColor (name )
97- return info {initials : initials , color : color }
116+ colorHash := getInitialsColorHash (name )
117+ color := getColorFromHash (colorHash )
118+ return info {initials : initials , colorHash : colorHash , color : color }
98119}
99120
100121func getInitials (name string ) string {
@@ -108,18 +129,26 @@ func getInitials(name string) string {
108129 }
109130 switch len (initials ) {
110131 case 0 :
111- return "? "
132+ return ""
112133 case 1 :
113134 return string (initials )
114135 default :
115136 return string (initials [0 ]) + string (initials [len (initials )- 1 ])
116137 }
117138}
118139
119- func getColor (name string ) string {
140+ func getInitialsColorHash (name string ) int {
120141 sum := 0
121142 for i := 0 ; i < len (name ); i ++ {
122143 sum += int (name [i ])
123144 }
124- return colors [sum % len (colors )]
145+ return sum
146+ }
147+
148+ func getColorFromHash (hash int ) string {
149+ return colors [hash % len (colors )]
150+ }
151+
152+ func getColor (name string ) string {
153+ return getColorFromHash (getInitialsColorHash (name ))
125154}
0 commit comments