forked from joejulian/gio
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:
+10
-9
@@ -29,6 +29,7 @@ type Family struct {
|
|||||||
|
|
||||||
layoutCache layoutCache
|
layoutCache layoutCache
|
||||||
pathCache pathCache
|
pathCache pathCache
|
||||||
|
buf sfnt.Buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
// for returns a font for the given face.
|
// 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 {
|
if l, ok := f.layoutCache.Get(lk); ok {
|
||||||
return l
|
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)
|
f.layoutCache.Put(lk, l)
|
||||||
return 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 {
|
if p, ok := f.pathCache.Get(pk); ok {
|
||||||
return p
|
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)
|
f.pathCache.Put(pk, p)
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func layoutText(ppem fixed.Int26_6, str string, f *opentype, opts text.LayoutOptions) *text.Layout {
|
func layoutText(buf *sfnt.Buffer, ppem fixed.Int26_6, str string, f *opentype, opts text.LayoutOptions) *text.Layout {
|
||||||
m := f.Metrics(ppem)
|
m := f.Metrics(buf, ppem)
|
||||||
lineTmpl := text.Line{
|
lineTmpl := text.Line{
|
||||||
Ascent: m.Ascent,
|
Ascent: m.Ascent,
|
||||||
// m.Height is equal to m.Ascent + m.Descent + linegap.
|
// m.Height is equal to m.Ascent + m.Descent + linegap.
|
||||||
// Compute the descent including the linegap.
|
// Compute the descent including the linegap.
|
||||||
Descent: m.Height - m.Ascent,
|
Descent: m.Height - m.Ascent,
|
||||||
Bounds: f.Bounds(ppem),
|
Bounds: f.Bounds(buf, ppem),
|
||||||
}
|
}
|
||||||
var lines []text.Line
|
var lines []text.Line
|
||||||
maxDotX := fixed.Int26_6(math.MaxInt32)
|
maxDotX := fixed.Int26_6(math.MaxInt32)
|
||||||
@@ -119,7 +120,7 @@ func layoutText(ppem fixed.Int26_6, str string, f *opentype, opts text.LayoutOpt
|
|||||||
c = ' '
|
c = ' '
|
||||||
s = 1
|
s = 1
|
||||||
}
|
}
|
||||||
a, ok := f.GlyphAdvance(ppem, c)
|
a, ok := f.GlyphAdvance(buf, ppem, c)
|
||||||
if !ok {
|
if !ok {
|
||||||
prev.idx += s
|
prev.idx += s
|
||||||
continue
|
continue
|
||||||
@@ -142,7 +143,7 @@ func layoutText(ppem fixed.Int26_6, str string, f *opentype, opts text.LayoutOpt
|
|||||||
next.adv = a
|
next.adv = a
|
||||||
var k fixed.Int26_6
|
var k fixed.Int26_6
|
||||||
if prev.valid {
|
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.
|
// Break the line if we're out of space.
|
||||||
if prev.idx > 0 && next.x+next.adv+k >= maxDotX {
|
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}
|
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 lastPos f32.Point
|
||||||
var builder paint.Path
|
var builder paint.Path
|
||||||
ops := new(op.Ops)
|
ops := new(op.Ops)
|
||||||
@@ -179,7 +180,7 @@ func textPath(ppem fixed.Int26_6, f *opentype, str text.String) op.MacroOp {
|
|||||||
builder.Begin(ops)
|
builder.Begin(ops)
|
||||||
for _, r := range str.String {
|
for _, r := range str.String {
|
||||||
if !unicode.IsSpace(r) {
|
if !unicode.IsSpace(r) {
|
||||||
segs, ok := f.LoadGlyph(ppem, r)
|
segs, ok := f.LoadGlyph(buf, ppem, r)
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-16
@@ -11,51 +11,49 @@ import (
|
|||||||
type opentype struct {
|
type opentype struct {
|
||||||
Font *sfnt.Font
|
Font *sfnt.Font
|
||||||
Hinting font.Hinting
|
Hinting font.Hinting
|
||||||
|
|
||||||
buf sfnt.Buffer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *opentype) GlyphAdvance(ppem fixed.Int26_6, r rune) (advance fixed.Int26_6, ok bool) {
|
func (f *opentype) GlyphAdvance(buf *sfnt.Buffer, ppem fixed.Int26_6, r rune) (advance fixed.Int26_6, ok bool) {
|
||||||
g, err := f.Font.GlyphIndex(&f.buf, r)
|
g, err := f.Font.GlyphIndex(buf, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, false
|
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
|
return adv, err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *opentype) Kern(ppem fixed.Int26_6, r0, r1 rune) fixed.Int26_6 {
|
func (f *opentype) Kern(buf *sfnt.Buffer, ppem fixed.Int26_6, r0, r1 rune) fixed.Int26_6 {
|
||||||
g0, err := f.Font.GlyphIndex(&f.buf, r0)
|
g0, err := f.Font.GlyphIndex(buf, r0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
g1, err := f.Font.GlyphIndex(&f.buf, r1)
|
g1, err := f.Font.GlyphIndex(buf, r1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0
|
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 {
|
if err != nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return adv
|
return adv
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *opentype) Metrics(ppem fixed.Int26_6) font.Metrics {
|
func (f *opentype) Metrics(buf *sfnt.Buffer, ppem fixed.Int26_6) font.Metrics {
|
||||||
m, _ := f.Font.Metrics(&f.buf, ppem, f.Hinting)
|
m, _ := f.Font.Metrics(buf, ppem, f.Hinting)
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *opentype) Bounds(ppem fixed.Int26_6) fixed.Rectangle26_6 {
|
func (f *opentype) Bounds(buf *sfnt.Buffer, ppem fixed.Int26_6) fixed.Rectangle26_6 {
|
||||||
r, _ := f.Font.Bounds(&f.buf, ppem, f.Hinting)
|
r, _ := f.Font.Bounds(buf, ppem, f.Hinting)
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *opentype) LoadGlyph(ppem fixed.Int26_6, r rune) ([]sfnt.Segment, bool) {
|
func (f *opentype) LoadGlyph(buf *sfnt.Buffer, ppem fixed.Int26_6, r rune) ([]sfnt.Segment, bool) {
|
||||||
g, err := f.Font.GlyphIndex(&f.buf, r)
|
g, err := f.Font.GlyphIndex(buf, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false
|
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 {
|
if err != nil {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user