mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 10:48:53 +01:00
text/v2: define different key types for StdFace and GoTextFaceSource
This commit is contained in:
parent
57ae07eb36
commit
03a8aaee5c
@ -18,8 +18,6 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"golang.org/x/image/math/fixed"
|
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2"
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/hook"
|
"github.com/hajimehoshi/ebiten/v2/internal/hook"
|
||||||
)
|
)
|
||||||
@ -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 {
|
type glyphImageCacheEntry struct {
|
||||||
image *ebiten.Image
|
image *ebiten.Image
|
||||||
atime int64
|
atime int64
|
||||||
}
|
}
|
||||||
|
|
||||||
type glyphImageCache struct {
|
type glyphImageCache[Key comparable] struct {
|
||||||
cache map[glyphImageCacheKey]*glyphImageCacheEntry
|
cache map[Key]*glyphImageCacheEntry
|
||||||
m sync.Mutex
|
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()
|
g.m.Lock()
|
||||||
defer g.m.Unlock()
|
defer g.m.Unlock()
|
||||||
|
|
||||||
@ -70,7 +58,7 @@ func (g *glyphImageCache) getOrCreate(face Face, key glyphImageCacheKey, create
|
|||||||
}
|
}
|
||||||
|
|
||||||
if g.cache == nil {
|
if g.cache == nil {
|
||||||
g.cache = map[glyphImageCacheKey]*glyphImageCacheEntry{}
|
g.cache = map[Key]*glyphImageCacheEntry{}
|
||||||
}
|
}
|
||||||
|
|
||||||
img := create()
|
img := create()
|
||||||
|
@ -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),
|
X: (origin.X + b.Min.X) & ((1 << 6) - 1),
|
||||||
Y: (origin.Y + b.Min.Y) & ((1 << 6) - 1),
|
Y: (origin.Y + b.Min.Y) & ((1 << 6) - 1),
|
||||||
}
|
}
|
||||||
key := glyphImageCacheKey{
|
key := goTextGlyphImageCacheKey{
|
||||||
id: uint32(glyph.shapingGlyph.GlyphID),
|
gid: glyph.shapingGlyph.GlyphID,
|
||||||
xoffset: subpixelOffset.X,
|
xoffset: subpixelOffset.X,
|
||||||
yoffset: subpixelOffset.Y,
|
yoffset: subpixelOffset.Y,
|
||||||
variations: g.ensureVariationsString(),
|
variations: g.ensureVariationsString(),
|
||||||
|
@ -52,12 +52,19 @@ type goTextOutputCacheValue struct {
|
|||||||
atime int64
|
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.
|
// GoTextFaceSource is a source of a GoTextFace. This can be shared by multiple GoTextFace objects.
|
||||||
type GoTextFaceSource struct {
|
type GoTextFaceSource struct {
|
||||||
f font.Face
|
f font.Face
|
||||||
|
|
||||||
outputCache map[goTextOutputCacheKey]*goTextOutputCacheValue
|
outputCache map[goTextOutputCacheKey]*goTextOutputCacheValue
|
||||||
glyphImageCache map[float64]*glyphImageCache
|
glyphImageCache map[float64]*glyphImageCache[goTextGlyphImageCacheKey]
|
||||||
|
|
||||||
addr *GoTextFaceSource
|
addr *GoTextFaceSource
|
||||||
|
|
||||||
@ -224,12 +231,12 @@ func (g *GoTextFaceSource) scale(size float64) float64 {
|
|||||||
return size / float64(g.f.Upem())
|
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 {
|
if g.glyphImageCache == nil {
|
||||||
g.glyphImageCache = map[float64]*glyphImageCache{}
|
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{}
|
g.glyphImageCache[goTextFace.Size] = &glyphImageCache[goTextGlyphImageCacheKey]{}
|
||||||
}
|
}
|
||||||
return g.glyphImageCache[goTextFace.Size].getOrCreate(goTextFace, key, create)
|
return g.glyphImageCache[goTextFace.Size].getOrCreate(goTextFace, key, create)
|
||||||
}
|
}
|
||||||
|
@ -26,13 +26,20 @@ import (
|
|||||||
|
|
||||||
var _ Face = (*StdFace)(nil)
|
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 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 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.
|
// StdFace must not be copied by value.
|
||||||
type StdFace struct {
|
type StdFace struct {
|
||||||
f *faceWithCache
|
f *faceWithCache
|
||||||
|
|
||||||
glyphImageCache glyphImageCache
|
glyphImageCache glyphImageCache[stdFaceGlyphImageCacheKey]
|
||||||
|
|
||||||
addr *StdFace
|
addr *StdFace
|
||||||
}
|
}
|
||||||
@ -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),
|
X: (origin.X + b.Min.X) & ((1 << 6) - 1),
|
||||||
Y: (origin.Y + b.Min.Y) & ((1 << 6) - 1),
|
Y: (origin.Y + b.Min.Y) & ((1 << 6) - 1),
|
||||||
}
|
}
|
||||||
key := glyphImageCacheKey{
|
key := stdFaceGlyphImageCacheKey{
|
||||||
id: uint32(r),
|
rune: r,
|
||||||
xoffset: subpixelOffset.X,
|
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 {
|
img := s.glyphImageCache.getOrCreate(s, key, func() *ebiten.Image {
|
||||||
return s.glyphImageImpl(r, subpixelOffset, b)
|
return s.glyphImageImpl(r, subpixelOffset, b)
|
||||||
|
Loading…
Reference in New Issue
Block a user