~eliasnaur/gio

25171df66ae1ec92635392337aafdb4497ee68c3 — Chris Waldon 6 months ago 3bdbcab
text: cache bitmap glyph image operations

This commit adds caching to the process of extracting bitmap images
from glyphs, ensuring that we only do so once for a given glyph so long
as it isn't evicted from our LRU.

Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
1 files changed, 23 insertions(+), 13 deletions(-)

M text/gotext.go
M text/gotext.go => text/gotext.go +23 -13
@@ 262,6 262,9 @@ type shaperImpl struct {
	splitScratch1, splitScratch2 []shaping.Input
	outScratchBuf                []shaping.Output
	scratchRunes                 []rune

	// bitmapGlyphCache caches extracted bitmap glyph images.
	bitmapGlyphCache bitmapCache
}

// Load registers the provided FontFace with the shaper, if it is compatible.


@@ 592,20 595,27 @@ func (s *shaperImpl) Bitmaps(ops *op.Ops, gs []Glyph) op.CallOp {
		case api.GlyphBitmap:
			var imgOp paint.ImageOp
			var imgSize image.Point
			var img image.Image
			switch glyphData.Format {
			case api.PNG, api.JPG, api.TIFF:
				img, _, _ = image.Decode(bytes.NewReader(glyphData.Data))
			case api.BlackAndWhite:
				// This is a complex family of uncompressed bitmaps that don't seem to be
				// very common in practice. We can try adding support later if needed.
				fallthrough
			default:
				// Unknown format.
				continue
			bitmapData, ok := s.bitmapGlyphCache.Get(g.ID)
			if !ok {
				var img image.Image
				switch glyphData.Format {
				case api.PNG, api.JPG, api.TIFF:
					img, _, _ = image.Decode(bytes.NewReader(glyphData.Data))
				case api.BlackAndWhite:
					// This is a complex family of uncompressed bitmaps that don't seem to be
					// very common in practice. We can try adding support later if needed.
					fallthrough
				default:
					// Unknown format.
					continue
				}
				imgOp = paint.NewImageOp(img)
				imgSize = img.Bounds().Size()
				s.bitmapGlyphCache.Put(g.ID, bitmap{img: imgOp, size: imgSize})
			} else {
				imgOp = bitmapData.img
				imgSize = bitmapData.size
			}
			imgOp = paint.NewImageOp(img)
			imgSize = img.Bounds().Size()
			off := op.Offset(image.Point{
				X: ((g.X - x) - g.Offset.X).Round(),
				Y: g.Offset.Y.Round() - g.Ascent.Round(),