46 lines
1.1 KiB
Go
46 lines
1.1 KiB
Go
package typeset
|
|
|
|
import "golang.org/x/image/font"
|
|
import "golang.org/x/image/math/fixed"
|
|
|
|
func measure (tokens []token, face font.Face) {
|
|
var lastRune rune
|
|
for index, token := range tokens {
|
|
var x fixed.Int26_6
|
|
for index, runl := range token.runes {
|
|
advance, ok := face.GlyphAdvance(runl.run)
|
|
if !ok { advance = tofuAdvance(face) }
|
|
advance += face.Kern(lastRune, runl.run)
|
|
|
|
runl.x = x
|
|
x += advance
|
|
lastRune = runl.run
|
|
token.runes[index] = runl
|
|
}
|
|
token.width = x
|
|
tokens[index] = token
|
|
}
|
|
}
|
|
|
|
const tofuStandinRune = 'M'
|
|
const fallbackTofuAdvance = 16
|
|
const fallbackTofuWidth = 14
|
|
const fallbackTofuAscend = 16
|
|
|
|
func tofuAdvance (face font.Face) fixed.Int26_6 {
|
|
if advance, ok := face.GlyphAdvance(tofuStandinRune); ok {
|
|
return advance
|
|
} else {
|
|
return fallbackTofuAdvance
|
|
}
|
|
}
|
|
|
|
func tofuBounds (face font.Face) (fixed.Rectangle26_6, fixed.Int26_6) {
|
|
if bounds, advance, ok := face.GlyphBounds(tofuStandinRune); ok {
|
|
return bounds, advance
|
|
} else {
|
|
return fixed.R(0, -fallbackTofuAscend, fallbackTofuWidth, 0),
|
|
fallbackTofuAdvance
|
|
}
|
|
}
|