diff --git a/example/truetype/main.go b/example/truetype/main.go index 5fc72f7..9f52cd1 100644 --- a/example/truetype/main.go +++ b/example/truetype/main.go @@ -77,4 +77,12 @@ func main() { printGlyph(g) i1 := f.Index(c1) fmt.Printf("\n'%c', '%c' Kern:%d\n", c0, c1, f.Kern(fupe, i0, i1)) + + fmt.Printf("\nThe numbers above are in FUnits.\n" + + "The numbers below are in 26.6 fixed point pixels, at 12pt and 72dpi.\n\n") + a := truetype.NewFace(f, &truetype.Options{ + Size: 12, + DPI: 72, + }) + fmt.Printf("%#v\n", a.Metrics()) } diff --git a/truetype/face.go b/truetype/face.go index d64a014..099006f 100644 --- a/truetype/face.go +++ b/truetype/face.go @@ -7,6 +7,7 @@ package truetype import ( "image" + "math" "github.com/golang/freetype/raster" "golang.org/x/image/font" @@ -249,6 +250,17 @@ func (a *face) index(r rune) Index { // Close satisfies the font.Face interface. func (a *face) Close() error { return nil } +// Metrics satisfies the font.Face interface. +func (a *face) Metrics() font.Metrics { + scale := float64(a.scale) + fupe := float64(a.f.FUnitsPerEm()) + return font.Metrics{ + Height: a.scale, + Ascent: fixed.Int26_6(math.Ceil(scale * float64(+a.f.ascent) / fupe)), + Descent: fixed.Int26_6(math.Ceil(scale * float64(-a.f.descent) / fupe)), + } +} + // Kern satisfies the font.Face interface. func (a *face) Kern(r0, r1 rune) fixed.Int26_6 { i0 := a.index(r0) diff --git a/truetype/truetype.go b/truetype/truetype.go index 75cb733..613fc17 100644 --- a/truetype/truetype.go +++ b/truetype/truetype.go @@ -184,7 +184,9 @@ type Font struct { locaOffsetFormat int nGlyph, nHMetric, nKern int fUnitsPerEm int32 - bounds fixed.Rectangle26_6 + ascent int32 // In FUnits. + descent int32 // In FUnits; typically negative. + bounds fixed.Rectangle26_6 // In FUnits. // Values from the maxp section. maxTwilightPoints, maxStorage, maxFunctionDefs, maxStackElements uint16 } @@ -289,6 +291,8 @@ func (f *Font) parseHhea() error { if len(f.hhea) != 36 { return FormatError(fmt.Sprintf("bad hhea length: %d", len(f.hhea))) } + f.ascent = int32(int16(u16(f.hhea, 4))) + f.descent = int32(int16(u16(f.hhea, 6))) 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)))