text/v2: refactoring

This commit is contained in:
Hajime Hoshi 2024-10-27 21:44:17 +09:00
parent 2fab556dd9
commit 41e8d063e8
3 changed files with 17 additions and 9 deletions

View File

@ -45,10 +45,12 @@ type glyphImageCacheEntry struct {
type glyphImageCache[Key comparable] struct { type glyphImageCache[Key comparable] struct {
cache map[Key]*glyphImageCacheEntry cache map[Key]*glyphImageCacheEntry
atime int64 atime int64
glyphVariationCount int
m sync.Mutex m sync.Mutex
} }
func (g *glyphImageCache[Key]) getOrCreate(face Face, key Key, create func() *ebiten.Image) *ebiten.Image { func (g *glyphImageCache[Key]) getOrCreate(key Key, create func() *ebiten.Image) *ebiten.Image {
g.m.Lock() g.m.Lock()
defer g.m.Unlock() defer g.m.Unlock()
@ -83,7 +85,7 @@ func (g *glyphImageCache[Key]) getOrCreate(face Face, key Key, create func() *eb
// If the number of glyphs exceeds this soft limits, old glyphs are removed. // If the number of glyphs exceeds this soft limits, old glyphs are removed.
// Even after cleaning up the cache, the number of glyphs might still exceed the soft limit, but // Even after cleaning up the cache, the number of glyphs might still exceed the soft limit, but
// this is fine. // this is fine.
cacheSoftLimit := 128 * glyphVariationCount(face) cacheSoftLimit := 128 * g.glyphVariationCount
if len(g.cache) > cacheSoftLimit { if len(g.cache) > cacheSoftLimit {
for key, e := range g.cache { for key, e := range g.cache {
// 60 is an arbitrary number. // 60 is an arbitrary number.

View File

@ -287,9 +287,11 @@ func (g *GoTextFaceSource) getOrCreateGlyphImage(goTextFace *GoTextFace, key goT
g.glyphImageCache = map[float64]*glyphImageCache[goTextGlyphImageCacheKey]{} g.glyphImageCache = map[float64]*glyphImageCache[goTextGlyphImageCacheKey]{}
} }
if _, ok := g.glyphImageCache[goTextFace.Size]; !ok { if _, ok := g.glyphImageCache[goTextFace.Size]; !ok {
g.glyphImageCache[goTextFace.Size] = &glyphImageCache[goTextGlyphImageCacheKey]{} g.glyphImageCache[goTextFace.Size] = &glyphImageCache[goTextGlyphImageCacheKey]{
glyphVariationCount: glyphVariationCount(goTextFace),
} }
return g.glyphImageCache[goTextFace.Size].getOrCreate(goTextFace, key, create) }
return g.glyphImageCache[goTextFace.Size].getOrCreate(key, create)
} }
type singleFontmap struct { type singleFontmap struct {

View File

@ -43,7 +43,7 @@ type goXFaceGlyphImageCacheKey struct {
type GoXFace struct { type GoXFace struct {
f *faceWithCache f *faceWithCache
glyphImageCache glyphImageCache[goXFaceGlyphImageCacheKey] glyphImageCache *glyphImageCache[goXFaceGlyphImageCacheKey]
cachedMetrics Metrics cachedMetrics Metrics
@ -57,7 +57,11 @@ func NewGoXFace(face font.Face) *GoXFace {
f: face, f: face,
}, },
} }
// Set addr as early as possible. This is necessary for glyphVariationCount.
s.addr = s s.addr = s
s.glyphImageCache = &glyphImageCache[goXFaceGlyphImageCacheKey]{
glyphVariationCount: glyphVariationCount(s),
}
return s return s
} }
@ -170,7 +174,7 @@ func (s *GoXFace) glyphImage(r rune, origin fixed.Point26_6) (*ebiten.Image, int
rune: r, rune: r,
xoffset: subpixelOffset.X, xoffset: subpixelOffset.X,
} }
img := s.glyphImageCache.getOrCreate(s, key, func() *ebiten.Image { img := s.glyphImageCache.getOrCreate(key, func() *ebiten.Image {
return s.glyphImageImpl(r, subpixelOffset, b) return s.glyphImageImpl(r, subpixelOffset, b)
}) })
imgX := (origin.X + b.Min.X).Floor() imgX := (origin.X + b.Min.X).Floor()