text/shape: reduce garbage a bit

The sfnt.Buffer embedded in the opentype type caused instances of
it to escape. Move the buffer to Family to avoid that.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2019-10-05 22:53:37 +02:00
parent e8ca986a63
commit 1b44594411
2 changed files with 24 additions and 25 deletions
+10 -9
View File
@@ -29,6 +29,7 @@ type Family struct {
layoutCache layoutCache
pathCache pathCache
buf sfnt.Buffer
}
// for returns a font for the given face.
@@ -58,7 +59,7 @@ func (f *Family) Layout(face text.Face, size float32, str string, opts text.Layo
if l, ok := f.layoutCache.Get(lk); ok {
return l
}
l := layoutText(ppem, str, &opentype{Font: fnt, Hinting: font.HintingFull}, opts)
l := layoutText(&f.buf, ppem, str, &opentype{Font: fnt, Hinting: font.HintingFull}, opts)
f.layoutCache.Put(lk, l)
return l
}
@@ -74,19 +75,19 @@ func (f *Family) Shape(face text.Face, size float32, str text.String) op.MacroOp
if p, ok := f.pathCache.Get(pk); ok {
return p
}
p := textPath(ppem, &opentype{Font: fnt, Hinting: font.HintingFull}, str)
p := textPath(&f.buf, ppem, &opentype{Font: fnt, Hinting: font.HintingFull}, str)
f.pathCache.Put(pk, p)
return p
}
func layoutText(ppem fixed.Int26_6, str string, f *opentype, opts text.LayoutOptions) *text.Layout {
m := f.Metrics(ppem)
func layoutText(buf *sfnt.Buffer, ppem fixed.Int26_6, str string, f *opentype, opts text.LayoutOptions) *text.Layout {
m := f.Metrics(buf, ppem)
lineTmpl := text.Line{
Ascent: m.Ascent,
// m.Height is equal to m.Ascent + m.Descent + linegap.
// Compute the descent including the linegap.
Descent: m.Height - m.Ascent,
Bounds: f.Bounds(ppem),
Bounds: f.Bounds(buf, ppem),
}
var lines []text.Line
maxDotX := fixed.Int26_6(math.MaxInt32)
@@ -119,7 +120,7 @@ func layoutText(ppem fixed.Int26_6, str string, f *opentype, opts text.LayoutOpt
c = ' '
s = 1
}
a, ok := f.GlyphAdvance(ppem, c)
a, ok := f.GlyphAdvance(buf, ppem, c)
if !ok {
prev.idx += s
continue
@@ -142,7 +143,7 @@ func layoutText(ppem fixed.Int26_6, str string, f *opentype, opts text.LayoutOpt
next.adv = a
var k fixed.Int26_6
if prev.valid {
k = f.Kern(ppem, prev.r, next.r)
k = f.Kern(buf, ppem, prev.r, next.r)
}
// Break the line if we're out of space.
if prev.idx > 0 && next.x+next.adv+k >= maxDotX {
@@ -168,7 +169,7 @@ func layoutText(ppem fixed.Int26_6, str string, f *opentype, opts text.LayoutOpt
return &text.Layout{Lines: lines}
}
func textPath(ppem fixed.Int26_6, f *opentype, str text.String) op.MacroOp {
func textPath(buf *sfnt.Buffer, ppem fixed.Int26_6, f *opentype, str text.String) op.MacroOp {
var lastPos f32.Point
var builder paint.Path
ops := new(op.Ops)
@@ -179,7 +180,7 @@ func textPath(ppem fixed.Int26_6, f *opentype, str text.String) op.MacroOp {
builder.Begin(ops)
for _, r := range str.String {
if !unicode.IsSpace(r) {
segs, ok := f.LoadGlyph(ppem, r)
segs, ok := f.LoadGlyph(buf, ppem, r)
if !ok {
continue
}
+14 -16
View File
@@ -11,51 +11,49 @@ import (
type opentype struct {
Font *sfnt.Font
Hinting font.Hinting
buf sfnt.Buffer
}
func (f *opentype) GlyphAdvance(ppem fixed.Int26_6, r rune) (advance fixed.Int26_6, ok bool) {
g, err := f.Font.GlyphIndex(&f.buf, r)
func (f *opentype) GlyphAdvance(buf *sfnt.Buffer, ppem fixed.Int26_6, r rune) (advance fixed.Int26_6, ok bool) {
g, err := f.Font.GlyphIndex(buf, r)
if err != nil {
return 0, false
}
adv, err := f.Font.GlyphAdvance(&f.buf, g, ppem, f.Hinting)
adv, err := f.Font.GlyphAdvance(buf, g, ppem, f.Hinting)
return adv, err == nil
}
func (f *opentype) Kern(ppem fixed.Int26_6, r0, r1 rune) fixed.Int26_6 {
g0, err := f.Font.GlyphIndex(&f.buf, r0)
func (f *opentype) Kern(buf *sfnt.Buffer, ppem fixed.Int26_6, r0, r1 rune) fixed.Int26_6 {
g0, err := f.Font.GlyphIndex(buf, r0)
if err != nil {
return 0
}
g1, err := f.Font.GlyphIndex(&f.buf, r1)
g1, err := f.Font.GlyphIndex(buf, r1)
if err != nil {
return 0
}
adv, err := f.Font.Kern(&f.buf, g0, g1, ppem, f.Hinting)
adv, err := f.Font.Kern(buf, g0, g1, ppem, f.Hinting)
if err != nil {
return 0
}
return adv
}
func (f *opentype) Metrics(ppem fixed.Int26_6) font.Metrics {
m, _ := f.Font.Metrics(&f.buf, ppem, f.Hinting)
func (f *opentype) Metrics(buf *sfnt.Buffer, ppem fixed.Int26_6) font.Metrics {
m, _ := f.Font.Metrics(buf, ppem, f.Hinting)
return m
}
func (f *opentype) Bounds(ppem fixed.Int26_6) fixed.Rectangle26_6 {
r, _ := f.Font.Bounds(&f.buf, ppem, f.Hinting)
func (f *opentype) Bounds(buf *sfnt.Buffer, ppem fixed.Int26_6) fixed.Rectangle26_6 {
r, _ := f.Font.Bounds(buf, ppem, f.Hinting)
return r
}
func (f *opentype) LoadGlyph(ppem fixed.Int26_6, r rune) ([]sfnt.Segment, bool) {
g, err := f.Font.GlyphIndex(&f.buf, r)
func (f *opentype) LoadGlyph(buf *sfnt.Buffer, ppem fixed.Int26_6, r rune) ([]sfnt.Segment, bool) {
g, err := f.Font.GlyphIndex(buf, r)
if err != nil {
return nil, false
}
segs, err := f.Font.LoadGlyph(&f.buf, g, ppem, nil)
segs, err := f.Font.LoadGlyph(buf, g, ppem, nil)
if err != nil {
return nil, false
}