text: give offest to getGlyphImage

Now getGlyphImage can focus on rendering and doesn't have to calculate
offsets.
This commit is contained in:
Hajime Hoshi 2022-11-25 15:03:32 +09:00
parent e98661c1d3
commit 56788cf8d9

View File

@ -20,7 +20,6 @@ package text
import ( import (
"image" "image"
"image/color" "image/color"
"math"
"sync" "sync"
"golang.org/x/image/font" "golang.org/x/image/font"
@ -49,21 +48,18 @@ func fixed26_6ToFloat64(x fixed.Int26_6) float64 {
return float64(x>>6) + float64(x&((1<<6)-1))/float64(1<<6) return float64(x>>6) + float64(x&((1<<6)-1))/float64(1<<6)
} }
func drawGlyph(dst *ebiten.Image, face font.Face, r rune, img *ebiten.Image, dx, dy fixed.Int26_6, op *ebiten.DrawImageOptions) { func drawGlyph(dst *ebiten.Image, face font.Face, r rune, img *ebiten.Image, topleft fixed.Point26_6, op *ebiten.DrawImageOptions) {
if img == nil { if img == nil {
return return
} }
b := getGlyphBounds(face, r)
op2 := &ebiten.DrawImageOptions{} op2 := &ebiten.DrawImageOptions{}
if op != nil { if op != nil {
*op2 = *op *op2 = *op
op2.GeoM.Reset() op2.GeoM.Reset()
} }
// Adjust the position to the integers. op2.GeoM.Translate(fixed26_6ToFloat64(topleft.X), fixed26_6ToFloat64(topleft.Y))
// The current glyph images assume that they are rendered on integer positions so far.
op2.GeoM.Translate(math.Floor(fixed26_6ToFloat64(dx+b.Min.X)), math.Floor(fixed26_6ToFloat64(dy+b.Min.Y)))
if op != nil { if op != nil {
op2.GeoM.Concat(op.GeoM) op2.GeoM.Concat(op.GeoM)
} }
@ -96,7 +92,7 @@ var (
glyphImageCache = map[font.Face]map[rune]*glyphImageCacheEntry{} glyphImageCache = map[font.Face]map[rune]*glyphImageCacheEntry{}
) )
func getGlyphImage(face font.Face, r rune) *ebiten.Image { func getGlyphImage(face font.Face, r rune, offset fixed.Point26_6) *ebiten.Image {
if _, ok := glyphImageCache[face]; !ok { if _, ok := glyphImageCache[face]; !ok {
glyphImageCache[face] = map[rune]*glyphImageCacheEntry{} glyphImageCache[face] = map[rune]*glyphImageCacheEntry{}
} }
@ -130,9 +126,9 @@ func getGlyphImage(face font.Face, r rune) *ebiten.Image {
Face: face, Face: face,
} }
// Adjust the dot position so that the glyph image can be rendered on integer positions.
x, y := -b.Min.X, -b.Min.Y x, y := -b.Min.X, -b.Min.Y
x, y = fixed.I(x.Ceil()), fixed.I(y.Ceil()) x += offset.X
y += offset.Y
d.Dot = fixed.Point26_6{X: x, Y: y} d.Dot = fixed.Point26_6{X: x, Y: y}
d.DrawString(string(r)) d.DrawString(string(r))
@ -242,8 +238,18 @@ func DrawWithOptions(dst *ebiten.Image, text string, face font.Face, options *eb
continue continue
} }
img := getGlyphImage(face, r) // Adjust the position to the integers.
drawGlyph(dst, face, r, img, dx, dy, options) // The current glyph images assume that they are rendered on integer positions so far.
b := getGlyphBounds(face, r)
offset := fixed.Point26_6{
X: b.Min.X & ((1 << 6) - 1),
Y: b.Min.Y & ((1 << 6) - 1),
}
img := getGlyphImage(face, r, offset)
drawGlyph(dst, face, r, img, fixed.Point26_6{
X: dx + b.Min.X - offset.X,
Y: dy + b.Min.Y - offset.Y,
}, options)
dx += glyphAdvance(face, r) dx += glyphAdvance(face, r)
prevR = r prevR = r
@ -348,7 +354,12 @@ func CacheGlyphs(face font.Face, text string) {
defer textM.Unlock() defer textM.Unlock()
for _, r := range text { for _, r := range text {
getGlyphImage(face, r) b := getGlyphBounds(face, r)
offset := fixed.Point26_6{
X: b.Min.X & ((1 << 6) - 1),
Y: b.Min.Y & ((1 << 6) - 1),
}
getGlyphImage(face, r, offset)
} }
} }
@ -435,15 +446,20 @@ func AppendGlyphs(glyphs []Glyph, face font.Face, text string) []Glyph {
continue continue
} }
if img := getGlyphImage(face, r); img != nil { b := getGlyphBounds(face, r)
offset := fixed.Point26_6{
X: b.Min.X & ((1 << 6) - 1),
Y: b.Min.Y & ((1 << 6) - 1),
}
if img := getGlyphImage(face, r, offset); img != nil {
b := getGlyphBounds(face, r) b := getGlyphBounds(face, r)
// Adjust the position to the integers. // Adjust the position to the integers.
// The current glyph images assume that they are rendered on integer positions so far. // The current glyph images assume that they are rendered on integer positions so far.
glyphs = append(glyphs, Glyph{ glyphs = append(glyphs, Glyph{
Rune: r, Rune: r,
Image: img, Image: img,
X: math.Floor(fixed26_6ToFloat64(pos.X + b.Min.X)), X: fixed26_6ToFloat64(pos.X + b.Min.X - offset.X),
Y: math.Floor(fixed26_6ToFloat64(pos.Y + b.Min.Y)), Y: fixed26_6ToFloat64(pos.Y + b.Min.Y - offset.Y),
}) })
} }
pos.X += glyphAdvance(face, r) pos.X += glyphAdvance(face, r)