text: make CacheGlyphs create all the sub-pixel variations (#2530)

Before this change, CacheGlyphs created only necessary glyphs wihtout
considering variations by sub-pixels in X direction. This was sometimes
unexpected when a user might want to prepare glyph cache with a string
including all the letters, instead of actual texts.

This change makes CacheGlyphs create all the sub-pixel variations of
the given runes.

Updates #2469
Closes #2528
This commit is contained in:
Hajime Hoshi 2023-01-07 23:22:55 +09:00 committed by GitHub
parent abece041f4
commit 6f4cb04ebb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -362,6 +362,9 @@ func BoundString(face font.Face, text string) image.Rectangle {
// merged into one draw call regardless of the size of the text.
//
// If a rune's glyph is already cached, CacheGlyphs does nothing for the rune.
//
// One rune can have multiple varitations of glyphs due to sub-pixels in X direction.
// CacheGlyphs creates all such variations for one rune, while Draw creates only necessary glyphs.
func CacheGlyphs(face font.Face, text string) {
textM.Lock()
defer textM.Unlock()
@ -377,11 +380,16 @@ func CacheGlyphs(face font.Face, text string) {
continue
}
b := getGlyphBounds(face, r)
offset := fixed.Point26_6{
X: (adjustOffsetGranularity(dx) + b.Min.X) & ((1 << 6) - 1),
Y: b.Min.Y & ((1 << 6) - 1),
// Cache all 4 variations for one rune (#2528).
for i := 0; i < 4; i++ {
offset := fixed.Point26_6{
X: (fixed.Int26_6(i*(1<<4)) + b.Min.X) & ((1 << 6) - 1),
Y: b.Min.Y & ((1 << 6) - 1),
}
getGlyphImage(face, r, offset)
}
getGlyphImage(face, r, offset)
dx += glyphAdvance(face, r)
prevR = r
}