mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 07:35:40 +00:00
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
|
||||
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
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user