From 9510804f225145eff52912656e2f3761aaa8b730 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= Date: Thu, 13 Apr 2023 11:25:17 +0800 Subject: [PATCH] feat: common update --- .github/workflows/golangci-lint.yml | 22 +++++++++ .github/workflows/test.yml | 21 +++++++++ .gitignore | 72 +++++++++++++++++++++++++++++ .travis.yml | 6 --- LICENSE | 23 +++++++++ draw.go | 22 ++++++--- draw_test.go | 6 +-- example/example.go | 4 +- go.mod | 8 ++++ go.sum | 35 ++++++++++++++ 10 files changed, 201 insertions(+), 18 deletions(-) create mode 100644 .github/workflows/golangci-lint.yml create mode 100644 .github/workflows/test.yml create mode 100644 .gitignore delete mode 100644 .travis.yml create mode 100644 go.mod create mode 100644 go.sum diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml new file mode 100644 index 0000000..fd6e37a --- /dev/null +++ b/.github/workflows/golangci-lint.yml @@ -0,0 +1,22 @@ +name: Lint +on: + push: + branches: + - main + pull_request: +permissions: + contents: read +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/setup-go@v3 + with: + go-version: 1.18 + - uses: actions/checkout@v3 + - name: golangci-lint + uses: golangci/golangci-lint-action@v3 + with: + version: latest + args: --timeout=10m --issues-exit-code=0 ./... diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..2c79e7b --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,21 @@ +name: Test +on: + push: + branches: + - main + pull_request: +jobs: + test: + strategy: + matrix: + go: [ '1.20', '1.19', '1.18' ] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: ${{ matrix.go }} + - name: Install dependencies + run: go mod tidy + - name: Run tests + run: go test ./... diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6b0f8d5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,72 @@ +tmp +.env +.history + +# Golang # +# `go test -c` 生成的二进制文件 +*.test +# go coverage 工具 +*.out +*.prof +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +# 编译文件 # +*.com +*.class +*.dll +*.exe +*.o +*.so + +# 压缩包 # +# Git 自带压缩,如果这些压缩包里有代码,建议解压后 commit +*.7z +*.dmg +*.gz +*.iso +*.jar +*.rar +*.tar +*.zip + +# 日志文件和数据库 # +*.log +*.sqlite +*.db + +# 临时文件 # +tmp/ +.tmp/ + +# 系统生成文件 # +.DS_Store +.DS_Store? +.AppleDouble +.LSOverride +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db +.TemporaryItems +.fseventsd +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# IDE 和编辑器 # +.idea/ +/go_build_* +out/ +.vscode/ +.vscode/settings.json +*.sublime* +__debug_bin +.project + +# 前端工具链 # +.sass-cache/* +node_modules/ diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 6e436ea..0000000 --- a/.travis.yml +++ /dev/null @@ -1,6 +0,0 @@ -language: go - -go: - - 1.5 - - 1.6 - - 1.7 diff --git a/LICENSE b/LICENSE index b244e90..64bc034 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,26 @@ +Package letteravatar: Copyright 2023 HaoZi-Team, The MIT License. + + The MIT License (MIT) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Package letteravatar: Copyright 2016 Grigory Dryapak, The MIT License. The MIT License (MIT) diff --git a/draw.go b/draw.go index 629804a..3ba28c2 100644 --- a/draw.go +++ b/draw.go @@ -19,6 +19,7 @@ type Options struct { Font *truetype.Font Palette []color.Color LetterColor color.Color + FontSize int // PaletteKey is used to pick the background color from the Palette. // Using the same PaletteKey leads to the same background color being picked. @@ -30,7 +31,7 @@ var defaultLetterColor = color.RGBA{0xf0, 0xf0, 0xf0, 0xf0} // Draw generates a new letter-avatar image of the given size using the given letter // with the given options. Default parameters are used if a nil *Options is passed. -func Draw(size int, letter rune, options *Options) (image.Image, error) { +func Draw(size int, letters []rune, options *Options) (image.Image, error) { font := defaultFont if options != nil && options.Font != nil { font = options.Font @@ -55,14 +56,18 @@ func Draw(size int, letter rune, options *Options) (image.Image, error) { } } - return drawAvatar(bgColor, letterColor, font, size, letter) + fontSize := float64(options.FontSize) + if options.FontSize == 0 { + fontSize = float64(size) * 0.6 + } + + return drawAvatar(bgColor, letterColor, font, size, fontSize, letters) } -func drawAvatar(bgColor, fgColor color.Color, font *truetype.Font, size int, letter rune) (image.Image, error) { +func drawAvatar(bgColor, fgColor color.Color, font *truetype.Font, size int, fontSize float64, letters []rune) (image.Image, error) { dst := newRGBA(size, size, bgColor) - fontSize := float64(size) * 0.6 - src, err := drawString(bgColor, fgColor, font, fontSize, string(letter)) + src, err := drawString(bgColor, fgColor, font, fontSize, letters) if err != nil { return nil, err } @@ -73,13 +78,16 @@ func drawAvatar(bgColor, fgColor color.Color, font *truetype.Font, size int, let return dst, nil } -func drawString(bgColor, fgColor color.Color, font *truetype.Font, fontSize float64, str string) (image.Image, error) { +func drawString(bgColor, fgColor color.Color, font *truetype.Font, fontSize float64, letters []rune) (image.Image, error) { c := freetype.NewContext() c.SetDPI(72) bb := font.Bounds(c.PointToFixed(fontSize)) w := bb.Max.X.Ceil() - bb.Min.X.Floor() h := bb.Max.Y.Ceil() - bb.Min.Y.Floor() + if len(letters) > 0 { + w = w + int(fontSize)*(len(letters)-1) + } dst := newRGBA(w, h, bgColor) src := image.NewUniform(fgColor) @@ -90,7 +98,7 @@ func drawString(bgColor, fgColor color.Color, font *truetype.Font, fontSize floa c.SetFontSize(fontSize) c.SetFont(font) - p, err := c.DrawString(str, fixed.Point26_6{X: 0, Y: bb.Max.Y}) + p, err := c.DrawString(string(letters), fixed.Point26_6{X: 0, Y: bb.Max.Y}) if err != nil { return nil, err } diff --git a/draw_test.go b/draw_test.go index a510c22..c04ceaf 100644 --- a/draw_test.go +++ b/draw_test.go @@ -60,7 +60,7 @@ func TestDraw(t *testing.T) { } for i, testcase := range testcases { - img, err := Draw(testcase.size, testcase.letter, testcase.options) + img, err := Draw(testcase.size, []rune{testcase.letter}, testcase.options) if err != nil { t.Fatalf("failed to create avatar #%d: %s", i, err) } @@ -80,14 +80,14 @@ func TestPaletteKey(t *testing.T) { } avatars := make(map[string]image.Image) for _, u := range users { - img, err := Draw(30, []rune(u)[0], &Options{PaletteKey: u}) + img, err := Draw(30, []rune(u), &Options{PaletteKey: u}) if err != nil { t.Fatalf("failed to create avatar for %s: %s", u, err) } avatars[u] = img } for _, u := range users { - img, err := Draw(30, []rune(u)[0], &Options{PaletteKey: u}) + img, err := Draw(30, []rune(u), &Options{PaletteKey: u}) if err != nil { t.Fatalf("failed to create avatar for %s: %s", u, err) } diff --git a/example/example.go b/example/example.go index 6f889df..871fc05 100644 --- a/example/example.go +++ b/example/example.go @@ -6,7 +6,7 @@ import ( "os" "unicode/utf8" - "github.com/disintegration/letteravatar" + "github.com/HaoZi-Team/letteravatar" ) var names = []string{ @@ -28,7 +28,7 @@ func main() { for _, name := range names { firstLetter, _ := utf8.DecodeRuneInString(name) - img, err := letteravatar.Draw(75, firstLetter, nil) + img, err := letteravatar.Draw(75, []rune{firstLetter}, nil) if err != nil { log.Fatal(err) } diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..d6b1fc3 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module github.com/HaoZi-Team/letteravatar + +go 1.18 + +require ( + github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 + golang.org/x/image v0.7.0 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..0a400cb --- /dev/null +++ b/go.sum @@ -0,0 +1,35 @@ +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/image v0.7.0 h1:gzS29xtG1J5ybQlv0PuyfE3nmc6R4qB73m6LUUmvFuw= +golang.org/x/image v0.7.0/go.mod h1:nd/q4ef1AKKYl/4kft7g+6UyGbdiqWqTP1ZAbRoV7Rg= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=