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  }