Skip to content

Commit

Permalink
text/v2: define different key types for StdFace and GoTextFaceSource
Browse files Browse the repository at this point in the history
  • Loading branch information
hajimehoshi committed Nov 19, 2023
1 parent 57ae07e commit 03a8aae
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 26 deletions.
20 changes: 4 additions & 16 deletions text/v2/glyph.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ import (
"math"
"sync"

"golang.org/x/image/math/fixed"

"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/internal/hook"
)
Expand All @@ -39,27 +37,17 @@ func init() {
})
}

type glyphImageCacheKey struct {
// id is rune for StdFace, and GID for GoTextFace.
id uint32

xoffset fixed.Int26_6
yoffset fixed.Int26_6

variations string
}

type glyphImageCacheEntry struct {
image *ebiten.Image
atime int64
}

type glyphImageCache struct {
cache map[glyphImageCacheKey]*glyphImageCacheEntry
type glyphImageCache[Key comparable] struct {
cache map[Key]*glyphImageCacheEntry
m sync.Mutex
}

func (g *glyphImageCache) getOrCreate(face Face, key glyphImageCacheKey, create func() *ebiten.Image) *ebiten.Image {
func (g *glyphImageCache[Key]) getOrCreate(face Face, key Key, create func() *ebiten.Image) *ebiten.Image {
g.m.Lock()
defer g.m.Unlock()

Expand All @@ -70,7 +58,7 @@ func (g *glyphImageCache) getOrCreate(face Face, key glyphImageCacheKey, create
}

if g.cache == nil {
g.cache = map[glyphImageCacheKey]*glyphImageCacheEntry{}
g.cache = map[Key]*glyphImageCacheEntry{}
}

img := create()
Expand Down
4 changes: 2 additions & 2 deletions text/v2/gotext.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,8 +329,8 @@ func (g *GoTextFace) glyphImage(glyph glyph, origin fixed.Point26_6) (*ebiten.Im
X: (origin.X + b.Min.X) & ((1 << 6) - 1),
Y: (origin.Y + b.Min.Y) & ((1 << 6) - 1),
}
key := glyphImageCacheKey{
id: uint32(glyph.shapingGlyph.GlyphID),
key := goTextGlyphImageCacheKey{
gid: glyph.shapingGlyph.GlyphID,
xoffset: subpixelOffset.X,
yoffset: subpixelOffset.Y,
variations: g.ensureVariationsString(),
Expand Down
15 changes: 11 additions & 4 deletions text/v2/gotextfacesource.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,19 @@ type goTextOutputCacheValue struct {
atime int64
}

type goTextGlyphImageCacheKey struct {
gid api.GID
xoffset fixed.Int26_6
yoffset fixed.Int26_6
variations string
}

// GoTextFaceSource is a source of a GoTextFace. This can be shared by multiple GoTextFace objects.
type GoTextFaceSource struct {
f font.Face

outputCache map[goTextOutputCacheKey]*goTextOutputCacheValue
glyphImageCache map[float64]*glyphImageCache
glyphImageCache map[float64]*glyphImageCache[goTextGlyphImageCacheKey]

addr *GoTextFaceSource

Expand Down Expand Up @@ -224,12 +231,12 @@ func (g *GoTextFaceSource) scale(size float64) float64 {
return size / float64(g.f.Upem())
}

func (g *GoTextFaceSource) getOrCreateGlyphImage(goTextFace *GoTextFace, key glyphImageCacheKey, create func() *ebiten.Image) *ebiten.Image {
func (g *GoTextFaceSource) getOrCreateGlyphImage(goTextFace *GoTextFace, key goTextGlyphImageCacheKey, create func() *ebiten.Image) *ebiten.Image {
if g.glyphImageCache == nil {
g.glyphImageCache = map[float64]*glyphImageCache{}
g.glyphImageCache = map[float64]*glyphImageCache[goTextGlyphImageCacheKey]{}
}
if _, ok := g.glyphImageCache[goTextFace.Size]; !ok {
g.glyphImageCache[goTextFace.Size] = &glyphImageCache{}
g.glyphImageCache[goTextFace.Size] = &glyphImageCache[goTextGlyphImageCacheKey]{}
}
return g.glyphImageCache[goTextFace.Size].getOrCreate(goTextFace, key, create)
}
14 changes: 10 additions & 4 deletions text/v2/std.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,20 @@ import (

var _ Face = (*StdFace)(nil)

type stdFaceGlyphImageCacheKey struct {
rune rune
xoffset fixed.Int26_6

// yoffset is always the same if the rune is the same, so this doesn't have to be a key.
}

// StdFace is a Face implementation for a semi-standard font.Face (golang.org/x/image/font).
// StdFace is useful to transit from existing codebase with text v1, or to use some bitmap fonts defined as font.Face.
// StdFace must not be copied by value.
type StdFace struct {
f *faceWithCache

glyphImageCache glyphImageCache
glyphImageCache glyphImageCache[stdFaceGlyphImageCacheKey]

addr *StdFace
}
Expand Down Expand Up @@ -121,10 +128,9 @@ func (s *StdFace) glyphImage(r rune, origin fixed.Point26_6) (*ebiten.Image, int
X: (origin.X + b.Min.X) & ((1 << 6) - 1),
Y: (origin.Y + b.Min.Y) & ((1 << 6) - 1),
}
key := glyphImageCacheKey{
id: uint32(r),
key := stdFaceGlyphImageCacheKey{
rune: r,
xoffset: subpixelOffset.X,
// yoffset is always the same if the rune is the same, so this doesn't have to be a key.
}
img := s.glyphImageCache.getOrCreate(s, key, func() *ebiten.Image {
return s.glyphImageImpl(r, subpixelOffset, b)
Expand Down

0 comments on commit 03a8aae

Please sign in to comment.