text/v2: improve rendering quality for small faces

Closes #2843
This commit is contained in:
Hajime Hoshi 2023-11-16 12:00:15 +09:00
parent 006777220c
commit 2e60c67ec9
3 changed files with 22 additions and 9 deletions

View File

@ -325,11 +325,11 @@ func (g *GoTextFace) appendGlyphs(glyphs []Glyph, text string, indexOffset int,
func (g *GoTextFace) glyphImage(glyph glyph, origin fixed.Point26_6) (*ebiten.Image, int, int) {
if g.direction().isHorizontal() {
origin.X = adjustGranularity(origin.X)
origin.X = adjustGranularity(origin.X, g)
origin.Y &^= ((1 << 6) - 1)
} else {
origin.X &^= ((1 << 6) - 1)
origin.Y = adjustGranularity(origin.Y)
origin.Y = adjustGranularity(origin.Y, g)
}
b := segmentsToBounds(glyph.scaledSegments)

View File

@ -130,7 +130,7 @@ func (s *StdFace) appendGlyphs(glyphs []Glyph, text string, indexOffset int, ori
func (s *StdFace) glyphImage(r rune, origin fixed.Point26_6) (*ebiten.Image, int, int, fixed.Int26_6) {
// Assume that StdFace's direction is always horizontal.
origin.X = adjustGranularity(origin.X)
origin.X = adjustGranularity(origin.X, s)
origin.Y &^= ((1 << 6) - 1)
b, a, _ := s.f.GlyphBounds(r)

View File

@ -95,10 +95,21 @@ func float64ToFixed26_6(x float64) fixed.Int26_6 {
return fixed.Int26_6(i)<<6 + fixed.Int26_6(frac*(1<<6))
}
const glyphVariationCount = 4
func glyphVariationCount(face Face) int {
m := face.Metrics()
if (m.HAscent != 0 || m.HDescent != 0) && m.HAscent+m.HDescent < 16 {
return 8
}
if (m.VAscent != 0 || m.VDescent != 0) && m.VAscent+m.VDescent < 16 {
return 8
}
// TODO: For big faces, a smaller value might be enough.
return 4
}
func adjustGranularity(x fixed.Int26_6) fixed.Int26_6 {
return x / ((1 << 6) / glyphVariationCount) * ((1 << 6) / glyphVariationCount)
func adjustGranularity(x fixed.Int26_6, face Face) fixed.Int26_6 {
c := glyphVariationCount(face)
return x / ((1 << 6) / fixed.Int26_6(c)) * ((1 << 6) / fixed.Int26_6(c))
}
// Glyph represents one glyph to render.
@ -227,16 +238,18 @@ func Measure(text string, face Face, lineHeight float64) (width, height float64)
func CacheGlyphs(text string, face Face) {
var x, y float64
c := glyphVariationCount(face)
var buf []Glyph
// Create all the possible variations (#2528).
for i := 0; i < 4; i++ {
for i := 0; i < c; i++ {
buf = appendGlyphs(buf, text, face, x, y, nil)
buf = buf[:0]
if face.direction().isHorizontal() {
x += 1.0 / glyphVariationCount
x += 1.0 / float64(c)
} else {
y += 1.0 / glyphVariationCount
y += 1.0 / float64(c)
}
}
}