diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 149d5c9..6cd7484 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - go: ['1.16'] + go: ['1.15', '1.16'] steps: - name: Setup uses: actions/setup-go@v3 diff --git a/finder.go b/finder.go index 757d0e5..df09dd8 100644 --- a/finder.go +++ b/finder.go @@ -1,7 +1,6 @@ package sysfont import ( - "os" "path/filepath" "strings" @@ -43,14 +42,7 @@ func NewFinder(opts *FinderOpts) *Finder { } var fonts []*Font - walker := func(filename string, info os.FileInfo, err error) error { - if err != nil { - return err - } - if info.IsDir() { - return nil - } - + findFonts(opts, func(filename string) error { // Check file extension. if extensions := opts.Extensions; len(extensions) > 0 { extension := filepath.Ext(strings.ToLower(filename)) @@ -67,14 +59,7 @@ func NewFinder(opts *FinderOpts) *Finder { fonts = append(fonts, matches...) return nil - } - - // Traverse OS font directories. - for _, dir := range opts.SearchPaths { - if err := filepath.Walk(dir, walker); err != nil { - continue - } - } + }) return &Finder{ fonts: fonts, diff --git a/finder_dirwalk.go b/finder_dirwalk.go new file mode 100644 index 0000000..d812713 --- /dev/null +++ b/finder_dirwalk.go @@ -0,0 +1,29 @@ +//go:build go1.16 +// +build go1.16 + +package sysfont + +import ( + "io/fs" + "path/filepath" +) + +func findFonts(opts *FinderOpts, fn func(filename string) error) { + walker := func(filename string, info fs.DirEntry, err error) error { + if err != nil { + return err + } + if info.IsDir() { + return nil + } + + return fn(filename) + } + + // Traverse OS font directories. + for _, dir := range opts.SearchPaths { + if err := filepath.WalkDir(dir, walker); err != nil { + continue + } + } +} diff --git a/finder_test.go b/finder_test.go new file mode 100644 index 0000000..64feafd --- /dev/null +++ b/finder_test.go @@ -0,0 +1,32 @@ +package sysfont + +import "testing" + +func TestFinder(t *testing.T) { + f := NewFinder(&FinderOpts{SearchPaths: []string{"testdata/fonts"}}) + fonts := f.List() + + // We expect Arial twice as we get double matches due to the lowercase and capitalised versions. + exp := []*Font{ + {Name: "Arial", Family: "Arial", Filename: "testdata/fonts/arial.ttf"}, + {Name: "Arial", Family: "Arial", Filename: "testdata/fonts/arial.ttf"}, + {Name: "Dingbats", Family: "Dingbats", Filename: "testdata/fonts/dingbats.ttc"}, + {Name: "Helvetica", Family: "Helvetica", Filename: "testdata/fonts/helvetica.otf"}, + } + + if len(fonts) != len(exp) { + t.Errorf("Expected %d fonts, got %d", len(exp), len(fonts)) + } + + for i, font := range fonts { + if font.Name != exp[i].Name { + t.Errorf("Expected font name %s, got %s", exp[i].Name, font.Name) + } + if font.Family != exp[i].Family { + t.Errorf("Expected font family %s, got %s", exp[i].Family, font.Family) + } + if font.Filename != exp[i].Filename { + t.Errorf("Expected font filename %s, got %s", exp[i].Filename, font.Filename) + } + } +} diff --git a/finder_walk.go b/finder_walk.go new file mode 100644 index 0000000..d7645c9 --- /dev/null +++ b/finder_walk.go @@ -0,0 +1,29 @@ +//go:build !go1.16 +// +build !go1.16 + +package sysfont + +import ( + "os" + "path/filepath" +) + +func findFonts(opts *FinderOpts, fn func(filename string) error) { + walker := func(filename string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() { + return nil + } + + return fn(filename) + } + + // Traverse OS font directories. + for _, dir := range opts.SearchPaths { + if err := filepath.Walk(dir, walker); err != nil { + continue + } + } +} diff --git a/testdata/fonts/arial.ttf b/testdata/fonts/arial.ttf new file mode 100644 index 0000000..e69de29 diff --git a/testdata/fonts/dingbats.ttc b/testdata/fonts/dingbats.ttc new file mode 100644 index 0000000..e69de29 diff --git a/testdata/fonts/helvetica.otf b/testdata/fonts/helvetica.otf new file mode 100644 index 0000000..e69de29