text: Change getGlyphImages to getGlyphImage to avoid allocating slices

This commit is contained in:
Hajime Hoshi 2021-01-05 12:21:41 +09:00
parent f77c514598
commit 927c477d2b

View File

@ -88,7 +88,7 @@ var (
emptyGlyphs = map[font.Face]map[rune]struct{}{} emptyGlyphs = map[font.Face]map[rune]struct{}{}
) )
func getGlyphImages(face font.Face, runes []rune) []*ebiten.Image { func getGlyphImage(face font.Face, r rune) *ebiten.Image {
if _, ok := emptyGlyphs[face]; !ok { if _, ok := emptyGlyphs[face]; !ok {
emptyGlyphs[face] = map[rune]struct{}{} emptyGlyphs[face] = map[rune]struct{}{}
} }
@ -96,34 +96,22 @@ func getGlyphImages(face font.Face, runes []rune) []*ebiten.Image {
glyphImageCache[face] = map[rune]*glyphImageCacheEntry{} glyphImageCache[face] = map[rune]*glyphImageCacheEntry{}
} }
imgs := make([]*ebiten.Image, len(runes))
glyphBounds := map[rune]fixed.Rectangle26_6{}
neededGlyphIndices := map[int]rune{}
for i, r := range runes {
if _, ok := emptyGlyphs[face][r]; ok { if _, ok := emptyGlyphs[face][r]; ok {
continue return nil
} }
if e, ok := glyphImageCache[face][r]; ok { if e, ok := glyphImageCache[face][r]; ok {
e.atime = now() e.atime = now()
imgs[i] = e.image return e.image
continue
} }
b := getGlyphBounds(face, r) b := getGlyphBounds(face, r)
w, h := (b.Max.X - b.Min.X).Ceil(), (b.Max.Y - b.Min.Y).Ceil() w, h := (b.Max.X - b.Min.X).Ceil(), (b.Max.Y - b.Min.Y).Ceil()
if w == 0 || h == 0 { if w == 0 || h == 0 {
emptyGlyphs[face][r] = struct{}{} emptyGlyphs[face][r] = struct{}{}
continue return nil
} }
glyphBounds[r] = b
neededGlyphIndices[i] = r
}
for i, r := range neededGlyphIndices {
b := glyphBounds[r]
w, h := (b.Max.X - b.Min.X).Ceil(), (b.Max.Y - b.Min.Y).Ceil()
if b.Min.X&((1<<6)-1) != 0 { if b.Min.X&((1<<6)-1) != 0 {
w++ w++
} }
@ -149,9 +137,8 @@ func getGlyphImages(face font.Face, runes []rune) []*ebiten.Image {
atime: now(), atime: now(),
} }
} }
imgs[i] = img
} return img
return imgs
} }
var textM sync.Mutex var textM sync.Mutex
@ -190,11 +177,9 @@ func Draw(dst *ebiten.Image, text string, face font.Face, x, y int, clr color.Co
faceHeight := face.Metrics().Height faceHeight := face.Metrics().Height
runes := []rune(text)
glyphImgs := getGlyphImages(face, runes)
colorm := colormcache.ColorToColorM(clr) colorm := colormcache.ColorToColorM(clr)
for i, r := range runes { for _, r := range text {
if prevR >= 0 { if prevR >= 0 {
fx += face.Kern(prevR, r) fx += face.Kern(prevR, r)
} }
@ -205,7 +190,8 @@ func Draw(dst *ebiten.Image, text string, face font.Face, x, y int, clr color.Co
continue continue
} }
drawGlyph(dst, face, r, glyphImgs[i], fx, fy, colorm) img := getGlyphImage(face, r)
drawGlyph(dst, face, r, img, fx, fy, colorm)
fx += glyphAdvance(face, r) fx += glyphAdvance(face, r)
prevR = r prevR = r
@ -254,7 +240,7 @@ func BoundString(face font.Face, text string) image.Rectangle {
prevR := rune(-1) prevR := rune(-1)
var bounds fixed.Rectangle26_6 var bounds fixed.Rectangle26_6
for _, r := range []rune(text) { for _, r := range text {
if prevR >= 0 { if prevR >= 0 {
fx += face.Kern(prevR, r) fx += face.Kern(prevR, r)
} }
@ -297,5 +283,7 @@ func CacheGlyphs(face font.Face, text string) {
textM.Lock() textM.Lock()
defer textM.Unlock() defer textM.Unlock()
getGlyphImages(face, []rune(text)) for _, r := range text {
getGlyphImage(face, r)
}
} }