github.com/gop9/olt@v0.0.0-20200202132135-d956aad50b08/framework/font/font_gio.go (about) 1 package font 2 3 import ( 4 "crypto/md5" 5 "sync" 6 7 "github.com/gop9/olt/gio/font/opentype" 8 "github.com/gop9/olt/gio/text" 9 "github.com/gop9/olt/gio/unit" 10 11 "golang.org/x/image/font" 12 "golang.org/x/image/math/fixed" 13 ) 14 15 type Face struct { 16 fnt *opentype.Font 17 shaper *text.Shaper 18 size int 19 fsize fixed.Int26_6 20 metrics font.Metrics 21 } 22 23 var fontsMu sync.Mutex 24 var fontsMap = map[[md5.Size]byte]*opentype.Font{} 25 26 func NewFace(ttf []byte, size int) (Face, error) { 27 key := md5.Sum(ttf) 28 fontsMu.Lock() 29 defer fontsMu.Unlock() 30 31 fnt, _ := fontsMap[key] 32 if fnt == nil { 33 var err error 34 fnt, err = opentype.Parse(ttf) 35 if err != nil { 36 return Face{}, err 37 } 38 } 39 40 shaper := &text.Shaper{} 41 shaper.Register(text.Font{}, fnt) 42 43 face := Face{fnt, shaper, size, fixed.I(size), font.Metrics{}} 44 metricsTxt := face.shaper.Layout(face, text.Font{}, "metrics", text.LayoutOptions{MaxWidth: 1e6}) 45 face.metrics.Ascent = metricsTxt.Lines[0].Ascent 46 face.metrics.Descent = metricsTxt.Lines[0].Descent 47 face.metrics.Height = face.metrics.Ascent + face.metrics.Descent 48 return face, nil 49 } 50 51 func (face Face) Px(v unit.Value) int { 52 return face.size 53 } 54 55 func (face Face) Metrics() font.Metrics { 56 return face.metrics 57 }