diff --git a/ofdgo.go b/ofdgo.go index ce90a32..9d852c5 100644 --- a/ofdgo.go +++ b/ofdgo.go @@ -76,6 +76,7 @@ func NewRenderer(reader *Reader, opts ...RendererOption) *Renderer { fontCache: make(map[fontCacheKey]*canvas.FontFamily), fontSourceCache: make(map[string][]fontSource), fontSourceUsed: make(map[string]fontSource), + fontDirCandidates: make(map[string][]fontFileCandidate), textGlyphPathCache: make(map[textGlyphPathCacheKey]textGlyphPathCacheValue), templatePageCache: make(map[string]*PageContent), } diff --git a/ofdgo_font_loader.go b/ofdgo_font_loader.go index a343b28..2997745 100644 --- a/ofdgo_font_loader.go +++ b/ofdgo_font_loader.go @@ -250,8 +250,12 @@ func (r *Renderer) loadFontSource(family *canvas.FontFamily, source fontSource, // 入参: dir 目录, patterns 模式列表, bold 是否粗体, italic 是否斜体 // 返回: []string 文件列表 func (r *Renderer) matchFontFiles(dir string, patterns []string, bold, italic bool) []string { - files, _ := filepath.Glob(filepath.Join(dir, "*")) - candidates := fontFileCandidates(files, filepath.Base) + candidates, ok := r.fontDirCandidates[dir] + if !ok { + files, _ := filepath.Glob(filepath.Join(dir, "*")) + candidates = fontFileCandidates(files, filepath.Base) + r.fontDirCandidates[dir] = candidates + } matches := make([]fontFileMatch, 0, len(candidates)) index := make(map[string]int, len(candidates)) for _, matcher := range newFontPatternMatchers(patterns) { diff --git a/ofdgo_renderer.go b/ofdgo_renderer.go index 5446273..df42c22 100644 --- a/ofdgo_renderer.go +++ b/ofdgo_renderer.go @@ -36,6 +36,7 @@ type Renderer struct { fontCache map[fontCacheKey]*canvas.FontFamily fontSourceCache map[string][]fontSource fontSourceUsed map[string]fontSource + fontDirCandidates map[string][]fontFileCandidate textGlyphPathCache map[textGlyphPathCacheKey]textGlyphPathCacheValue templatePageCache map[string]*PageContent fontDirs []string diff --git a/ofdgo_renderer_image.go b/ofdgo_renderer_image.go index e0ab8e9..4e6d0fd 100644 --- a/ofdgo_renderer_image.go +++ b/ofdgo_renderer_image.go @@ -266,28 +266,46 @@ func imageWithTransparentEdge(img image.Image) (image.Image, int) { if opaque, ok := source.(interface{ Opaque() bool }); ok && opaque.Opaque() { return img, 0 } - src := image.NewNRGBA(image.Rect(0, 0, w, h)) hasZero, hasVisible := false, false - for y := 0; y < h; y++ { - for x := 0; x < w; x++ { - c := imageNRGBAAt(source, bounds.Min.X+x, bounds.Min.Y+y) - src.SetNRGBA(x, y, c) - if c.A == 0 { - hasZero = true - } else { - hasVisible = true + src, ok := source.(*image.NRGBA) + if ok { + srcBounds := src.Bounds() + for y := srcBounds.Min.Y; y < srcBounds.Max.Y; y++ { + offset := src.PixOffset(srcBounds.Min.X, y) + 3 + for x := 0; x < w; x++ { + if src.Pix[offset] == 0 { + hasZero = true + } else { + hasVisible = true + } + offset += 4 + } + } + } else { + src = image.NewNRGBA(image.Rect(0, 0, w, h)) + for y := 0; y < h; y++ { + for x := 0; x < w; x++ { + c := imageNRGBAAt(source, bounds.Min.X+x, bounds.Min.Y+y) + src.SetNRGBA(x, y, c) + if c.A == 0 { + hasZero = true + } else { + hasVisible = true + } } } } if !hasZero || !hasVisible { return img, 0 } + srcBounds := src.Bounds() out := image.NewNRGBA(image.Rect(0, 0, w+2, h+2)) for y := 0; y < h; y++ { for x := 0; x < w; x++ { - c := src.NRGBAAt(x, y) + sx, sy := srcBounds.Min.X+x, srcBounds.Min.Y+y + c := src.NRGBAAt(sx, sy) if c.A == 0 { - if edge, ok := transparentEdgeColor(src, x, y); ok { + if edge, ok := transparentEdgeColor(src, sx, sy); ok { c = edge } }