add advanceCache map[rune] -- easy and major speedup; add reading of lineGap; fix Height computation to use ascent - descent + lineGap

This commit is contained in:
Randall C. O'Reilly 2018-08-16 23:41:02 -06:00
parent e21dad5cc8
commit 7946394216
2 changed files with 18 additions and 2 deletions

View file

@ -229,6 +229,7 @@ type face struct {
maxh int
glyphBuf GlyphBuf
indexCache [indexCacheLen]indexCacheEntry
advanceCache map[rune]fixed.Int26_6
// TODO: clip rectangle?
}
@ -255,9 +256,12 @@ func (a *face) Metrics() font.Metrics {
scale := float64(a.scale)
fupe := float64(a.f.FUnitsPerEm())
return font.Metrics{
Height: a.scale,
Height: fixed.Int26_6(math.Ceil(scale * float64(a.f.ascent-a.f.descent+a.f.lineGap) / fupe)),
Ascent: fixed.Int26_6(math.Ceil(scale * float64(+a.f.ascent) / fupe)),
Descent: fixed.Int26_6(math.Ceil(scale * float64(-a.f.descent) / fupe)),
// TODO: Metrics should include LineGap as a separate measure
// TODO: Would also be great to include Ex as in the height of an "x" --
// used widely for layout
}
}
@ -342,9 +346,17 @@ func (a *face) GlyphBounds(r rune) (bounds fixed.Rectangle26_6, advance fixed.In
}
func (a *face) GlyphAdvance(r rune) (advance fixed.Int26_6, ok bool) {
if a.advanceCache == nil {
a.advanceCache = make(map[rune]fixed.Int26_6, 1024)
}
advance, ok = a.advanceCache[r]
if ok {
return
}
if err := a.glyphBuf.Load(a.f, a.scale, a.index(r), a.hinting); err != nil {
return 0, false
}
a.advanceCache[r] = a.glyphBuf.AdvanceWidth
return a.glyphBuf.AdvanceWidth, true
}

View file

@ -187,6 +187,7 @@ type Font struct {
fUnitsPerEm int32
ascent int32 // In FUnits.
descent int32 // In FUnits; typically negative.
lineGap int32 // In FUnits.
bounds fixed.Rectangle26_6 // In FUnits.
// Values from the maxp section.
maxTwilightPoints, maxStorage, maxFunctionDefs, maxStackElements uint16
@ -294,6 +295,7 @@ func (f *Font) parseHhea() error {
}
f.ascent = int32(int16(u16(f.hhea, 4)))
f.descent = int32(int16(u16(f.hhea, 6)))
f.lineGap = int32(int16(u16(f.hhea, 8)))
f.nHMetric = int(u16(f.hhea, 34))
if 4*f.nHMetric+2*(f.nGlyph-f.nHMetric) != len(f.hmtx) {
return FormatError(fmt.Sprintf("bad hmtx length: %d", len(f.hmtx)))
@ -323,7 +325,9 @@ func (f *Font) parseKern() error {
}
version, offset := u16(f.kern, 0), 2
if version != 0 {
return UnsupportedError(fmt.Sprintf("kern version: %d", version))
f.nKern = 0
return nil
// return UnsupportedError(fmt.Sprintf("kern version: %d", version))
}
n, offset := u16(f.kern, offset), offset+2